Dela via


Trådpooler

En trådpool är en samling arbetstrådar som effektivt kör asynkrona återanrop för programmets räkning. Trådpoolen används främst för att minska antalet programtrådar och tillhandahålla hantering av arbetstrådarna. Program kan köa arbetsobjekt, associera arbete med väntebara referenser, automatiskt köa baserat på en timer och binda med I/O.

Arkitektur för trådpool

Följande program kan dra nytta av att använda en trådpool:

  • Ett program som är mycket parallellt och kan skicka ett stort antal små arbetsobjekt asynkront (till exempel distribuerad indexsökning eller nätverks-I/O).
  • Ett program som skapar och förstör ett stort antal trådar som körs under en kort tid. Med hjälp av trådpoolen kan du minska komplexiteten i trådhantering och de kostnader som krävs för att skapa och förstöra trådar.
  • Ett program som bearbetar oberoende arbetsobjekt i bakgrunden och parallellt (till exempel att läsa in flera flikar).
  • Ett program som måste utföra en exklusiv väntan på kernelobjekt eller blockera inkommande händelser på ett objekt. Att använda trådpoolen kan minska komplexiteten i trådhantering och öka prestandan genom att minska antalet kontextväxlar.
  • Ett program som skapar anpassade servitörtrådar för att vänta på händelser.

Den ursprungliga trådpoolen har omarbetats helt i Windows Vista. Den nya trådpoolen har förbättrats eftersom den har en enda arbetstrådstyp (stöder både I/O och icke-I/O), inte använder en timertråd, tillhandahåller en enda timerkö och tillhandahåller en dedikerad beständig tråd. Det ger också rensningsgrupper, högre prestanda, flera pooler per process som schemaläggs separat och ett nytt trådpools-API.

Trådpoolarkitekturen består av följande:

  • Arbetartrådar som kör återanropsfunktionerna
  • Servitörtrådar som väntar på flera väntehandtag
  • En arbetskö
  • En standardtrådspool för varje process
  • En arbetsfabrik som hanterar arbetstrådarna

Metodtips

Det nya trådpools-API:et ger mer flexibilitet och kontroll än ursprungliga. Det finns dock några subtila men viktiga skillnader. I det ursprungliga API:et var vänteåterställningen automatisk. i det nya API:et måste väntan uttryckligen återställas varje gång. Det ursprungliga API:et hanterade personifiering automatiskt och överför säkerhetskontexten för anropsprocessen till tråden. Med det nya API:et måste programmet uttryckligen ange säkerhetskontexten.

Följande är metodtips när du använder en trådpool:

  • Trådarna i en process delar trådpoolen. En enskild arbetstråd kan köra flera återanropsfunktioner, en i taget. Dessa arbetstrådar hanteras av trådpoolen. Avsluta därför inte en tråd från trådpoolen genom att anropa TerminateThread i tråden eller genom att anropa ExitThread från en återanropsfunktion.

  • En I/O-begäran kan köras på valfri tråd i trådpoolen. Att avbryta I/O i en trådpoolstråd kräver synkronisering eftersom funktionen avbryt kan köras på en annan tråd än den som hanterar I/O-begäran, vilket kan leda till att en okänd åtgärd avbryts. Undvik detta genom att alltid ange den OVERLAPPED- struktur som en I/O-begäran initierades med när CancelIoEx- anropas för asynkron I/O, eller använd din egen synkronisering för att säkerställa att inga andra I/O kan startas i måltråden innan du anropar antingen funktionen CancelSynchronousIo eller CancelIoEx.

  • Rensa alla resurser som skapats i återanropsfunktionen innan du återvänder från funktionen. Dessa omfattar TLS, säkerhetskontexter, trådprioritet och COM-registrering. Återanropsfunktioner måste också återställa trådtillståndet innan de returneras.

  • Håll väntehandtagen och deras associerade objekt vid liv tills trådpoolen har signalerat att den är klar med handtaget.

  • Markera alla trådar som väntar på långa åtgärder (till exempel I/O-tömningar eller resursrensning) så att trådpoolen kan allokera nya trådar i stället för att vänta på den här.

  • Innan du tar bort en DLL som använder trådpoolen avbryter du alla arbetsobjekt, I/O, vänteåtgärder och timers och väntar tills återanropen har körts.

  • Undvik dödlägen genom att eliminera beroenden mellan arbetsobjekt och mellan återanrop, genom att se till att en motringning inte väntar på att slutföras och genom att bevara trådprioriteten.

  • Köa inte för många objekt för snabbt i en process med andra komponenter med hjälp av standardtrådspoolen. Det finns en standardtrådspool per process, inklusive Svchost.exe. Som standard har varje trådpool högst 500 arbetstrådar. Trådpoolen försöker skapa fler arbetstrådar när antalet arbetstrådar i tillståndet redo/körs måste vara mindre än antalet processorer.

  • Undvik com-modellen med enkeltrådad lägenhet eftersom den är inkompatibel med trådpoolen. STA skapar trådtillstånd som kan påverka nästa arbetsobjekt för tråden. STA är vanligtvis långlivad och har trådtillhörighet, vilket är motsatsen till trådpoolen.

  • Skapa en ny trådpool för att styra trådprioritet och isolering, skapa anpassade egenskaper och eventuellt förbättra svarstiden. Ytterligare trådpooler kräver dock fler systemresurser (trådar, kernelminne). För många pooler ökar risken för CPU-konkurrens.

  • Använd om möjligt ett väntebart objekt i stället för en APC-baserad mekanism för att signalera en trådpoolstråd. API:er fungerar inte lika bra med trådpooltrådar som andra signalmekanismer eftersom systemet styr livslängden för trådpooltrådar, så det är möjligt att en tråd avslutas innan meddelandet levereras.

  • Använd felsökningstillägget för trådpoolen, !tp. Det här kommandot har följande användning:

    • pool adressflaggor
    • obj adressflaggor
    • tqueue adressflaggor
    • servitör adress
    • arbetsadress

    För pool, servitör och arbetare, om adressen är noll, dumpar kommandot alla objekt. För servitör och arbetare dumpar utelämnande av adressen den aktuella tråden. Följande flaggor definieras: 0x1 (enradsutdata), 0x2 (dumpmedlemmar) och 0x4 (dumppoolens arbetskö).

- för trådpoolen

Använda för trådpoolsfunktioner