multithreading - Tvinge kontekstomskifter i Windows

Indlæg af Hanne Mølgaard Plasc

Problem



Er der en måde at tvinge en kontekstomskifter i C ++ til en bestemt tråd, forudsat at jeg har trådhåndtaget eller tråd ID?

Bedste reference


Nej, du kan ikke tvinge operativsystemet til at køre den tråd, du vil have. Du kan bruge yield til at tvinge en kontekstomskifter dog ...


yield i Win32 API er funktion SwitchToThread. Hvis der ikke er nogen anden tråd tilgængelig til kørsel, vil en NUL -værdi blive returneret, og den aktuelle tråd vil fortsætte med at køre alligevel. [11]

Andre referencer 1


Du kan kun tilskynde Windows-trådplanlæggeren til at vælge en bestemt tråd, du kan ikke tvinge den. Du gør det først ved at gøre trådblokken på en synkroniseringsobjekt og signalere den. Sekundær ved at bumpe op sin prioritet.


Eksplicit konvertering af konvertering understøttes, du skal bruge fibre. Gennemgå SwitchToFiber (). En fiber er ikke en tråd med et langt skud, det ligner en gammel rutine. Fibers 'storhedstid er kommet og væk, de er ikke konkurrencedygtig med tråde længere. De har meget crappy cpu cache lokalitet og kan ikke drage fordel af flere kerner.

Andre referencer 2


Den eneste måde at tvinge en bestemt tråd på at køre er ved at bruge proces/tråd affinitet, men jeg kan ikke forestille mig nogensinde at have et problem, for hvilket dette var en rimelig løsning.


Den eneste måde at tvinge en kontekstkontakt på er at tvinge en tråd på en anden processor ved hjælp af affinitet.


Med andre ord, hvad du forsøger at gøre, er ikke virkelig levedygtigt.


Opkald SwitchToThread() vil resultere i en kontekstkontakt, hvis der er en anden tråd klar til at køre, der er kvalificeret til at køre på denne processor. Dokumentationen hedder det som følger: [12]



  Hvis du ringer til SwitchToThread-funktionen
  får operativsystemet til at skifte
  udførelse til en anden tråd, den
  returværdien er ikke-null.

  
  Hvis der ikke er andre tråde klar til
  køre, operativsystemet gør det ikke
  skifte eksekvering til en anden tråd,
  og returværdien er nul.


Andre referencer 3


Du kan midlertidigt stoppe prioriteten for den anden tråd, mens du løser med Sleep(0) opkald: dette overfører kontrol til andre tråde. Antag at den anden tråd har øget en lock variabel, og du skal vente til den bliver nul igen:


// Wait until other thread releases lock
SetThreadPriority(otherThread, THREAD\_PRIORITY\_HIGHER);
while (InterlockedRead(&lock) != 0)
  Sleep(0);
SetThreadPriority(otherThread, THREAD\_PRIORITY\_NORMAL);

Andre referencer 4


Jeg ville tjekke bogen Samtidig programmering til Windows. Planlæggeren synes at gøre et par ting værd at bemærke.


Søvn (0) giver kun højere prioriterede tråde (eller muligvis andre med samme prioritet). Det betyder, at du ikke kan løse prioriterede inversionssituationer med bare en søvn (0), hvor andre underordnede tråde skal køre. Du skal bruge SwitchToThread, Sove en varighed på ikke-nul eller helt blokere på nogle kernel HANDLE.

Andre referencer 5


Du kan oprette to synkroniseringsobjekter (f.eks. To begivenheder) og bruge API SignalObjectAndWait. [13] [14]


Hvis hObjectToWaitOn ikke er signaleret, og din anden tråd venter på hObjectToSignal, kan OS'et teoretisk udføre hurtig kontekstkontakt inde i denne API før slutningen af ​​tidsskiven.


Og hvis du vil have, at den aktuelle tråd automatisk genoptages, skal du blot oplyse en lille værdi (f.eks. 50 eller 100) på dwMilliseconds.