Szálkészletek
A szálkészlet feldolgozószálak gyűjteménye, amelyek hatékonyan hajtanak végre aszinkron visszahívásokat az alkalmazás nevében. A szálkészlet elsősorban az alkalmazásszálak számának csökkentésére és a feldolgozószálak felügyeletére szolgál. Az alkalmazások várólistára helyezhetik a munkaelemeket, hozzárendelhetik a munkát a várakozó fogópontokhoz, automatikusan sorba állíthatják az időzítőt, és kötést végezhetnek az I/O-val.
Szálkészlet architektúrája
A következő alkalmazások használhatnak szálkészletet:
- Egy rendkívül párhuzamos alkalmazás, amely nagy számú kis munkaelemet képes aszinkron módon elküldeni (például elosztott indexkeresést vagy hálózati I/O-t).
- Olyan alkalmazás, amely nagy számú szálat hoz létre és pusztít el, amelyek mindegyike rövid ideig fut. A szálkészlet használata csökkentheti a szálkezelés összetettségét, valamint a szálak létrehozásának és megsemmisítésének többletterhelését.
- Olyan alkalmazás, amely független munkaelemeket dolgoz fel a háttérben és párhuzamosan (például több lap betöltése).
- Olyan alkalmazás, amely kizárólagos várakozást kell végrehajtania a kernelobjektumokon, vagy blokkolnia kell a bejövő eseményeket egy objektumon. A szálkészlet használata csökkentheti a szálkezelés összetettségét, és növelheti a teljesítményt a környezeti kapcsolók számának csökkentésével.
- Olyan alkalmazás, amely egyéni pincérszálakat hoz létre az eseményekre való várakozáshoz.
Az eredeti szálkészlet teljesen újra lett tervezve a Windows Vista rendszerben. Az új szálkészlet azért lett továbbfejlesztve, mert egyetlen feldolgozószáltípust biztosít (az I/O-t és a nem I/O-t is támogatja), nem használ időzítőszálat, egyetlen időzítősort biztosít, és dedikált állandó szálat biztosít. Emellett tisztítási csoportokat, nagyobb teljesítményt, folyamatonként több készletet is biztosít, amelyek egymástól függetlenül vannak ütemezve, és egy új szálkészlet API-t is biztosít.
A szálkészlet architektúrája a következőkből áll:
- A visszahívási függvényeket végrehajtó feldolgozószálak
- Több várakozási fogóponton várakozó pincérszálak
- Munkahelyi üzenetsor
- Az egyes folyamatok alapértelmezett szálkészlete
- Feldolgozó-előállító, amely a feldolgozói szálakat kezeli
Ajánlott eljárások
Az új szálkészlet API- nagyobb rugalmasságot és vezérlést biztosít, mint az eredeti szálkészlet API-. Van azonban néhány apró, de fontos különbség. Az eredeti API-ban a várakozás visszaállítása automatikus volt; az új API-ban a várakozást minden alkalommal explicit módon alaphelyzetbe kell állítani. Az eredeti API automatikusan kezelte a megszemélyesítést, és átadta a hívási folyamat biztonsági környezetét a szálnak. Az új API-val az alkalmazásnak explicit módon kell beállítania a biztonsági környezetet.
A következő ajánlott eljárások a szálkészletek használatakor:
A folyamat szálai megosztják a szálkészletet. Egyetlen feldolgozószál egyszerre több visszahívási függvényt is végrehajthat. Ezeket a munkaszálakat a szálkészlet kezeli. Ezért ne fejezzen be egy szálat a szálkészletből úgy, hogy meghívja TerminateThread a szálon, vagy meghívja ExitThread egy visszahívási függvényből.
Az I/O-kérések a szálkészlet bármely szálán futtathatók. A szálkészlet-szál I/O-jának megszakítása szinkronizálást igényel, mert előfordulhat, hogy a megszakítási függvény az I/O-kérést kezelő száltól eltérő szálon fut, ami egy ismeretlen művelet törlését eredményezheti. Ennek elkerülése érdekében mindig adja meg azt a ÁTFEDÉSBEN lévő struktúrát, amellyel I/O-kérést indítottak CancelIoEx aszinkron I/O meghívásakor, vagy a saját szinkronizálásával győződjön meg arról, hogy a CancelSynchronousIo vagy CancelIoEx függvény meghívása előtt ne lehessen más I/O-t elindítani a célszálon.
Törölje a visszahívási függvényben létrehozott összes erőforrást, mielőtt visszatér a függvényből. Ezek közé tartozik a TLS, a biztonsági környezetek, a szál prioritása és a COM-regisztráció. A visszahívási függvénynek a visszatérés előtt vissza kell állítania a szál állapotát is.
Tartsa életben a várakozási fogópontokat és a hozzájuk tartozó objektumokat, amíg a szálkészlet nem jelzi, hogy az elkészült a fogóponttal.
Jelölje meg az összes olyan szálat, amely hosszadalmas műveletekre vár (például I/O-kiürítések vagy erőforrás-törlés), hogy a szálkészlet új szálakat foglalhassa le ahelyett, hogy erre várna.
Mielőtt eltávolítana egy, a szálkészletet használó DLL-t, szakítsa meg az összes munkaelemet, I/O-t, várakozási műveletet és időzítőt, és várja meg a visszahívások végrehajtását.
Kerülje a holtpontokat a munkaelemek és a visszahívások közötti függőségek megszüntetésével, azáltal, hogy biztosítja, hogy a visszahívások nem várnak magára, és megőrizze a szál prioritását.
Ne várjon túl sok elemet túl gyorsan egy folyamat során más összetevőkkel az alapértelmezett szálkészlet használatával. Folyamatonként egy alapértelmezett szálkészlet van, beleértve a Svchost.exe. Alapértelmezés szerint minden szálkészlet legfeljebb 500 feldolgozószállal rendelkezik. A szálkészlet több feldolgozószálat próbál létrehozni, ha a kész/futó állapotban lévő munkaszálak számának kisebbnek kell lennie, mint a processzorok száma.
Kerülje a COM egyszálas lakásmodellt, mivel nem kompatibilis a szálkészlettel. Az STA olyan szálállapotot hoz létre, amely hatással lehet a szál következő munkaelemére. Az STA általában hosszú élettartamú, és szál affinitással rendelkezik, ami a szálkészlet ellentéte.
Hozzon létre egy új szálkészletet a szál prioritásának és elkülönítésének szabályozásához, egyéni jellemzők létrehozásához és a válaszképesség javításához. A további szálkészletek azonban több rendszererőforrást igényelnek (szálak, kernelmemória). A túl sok készlet növeli a cpu-versengés lehetőségét.
Ha lehetséges, egy APC-alapú mechanizmus helyett használjon egy várható objektumot a szálkészlet szálának jelzéséhez. Az APC-k nem működnek olyan jól a szálkészlet-szálakkal, mint más jelzési mechanizmusok, mivel a rendszer szabályozza a szálkészlet szálainak élettartamát, így lehetséges, hogy egy szál le legyen állítva az értesítés kézbesítése előtt.
Használja a szálkészlet hibakereső bővítményét(!tp). Ez a parancs a következő használattal rendelkezik:
- készlet címjelzők
- obj címjelzők
- tqueue addressflags
- pincér cím
- feldolgozói cím
A készlet, a pincér és a feldolgozó esetében, ha a cím nulla, a parancs az összes objektumot memóriaképként használja. A pincér és a feldolgozó esetében a cím kihagyásával az aktuális szál törlődik. A következő jelzők vannak definiálva: 0x1 (egysoros kimenet), 0x2 (memóriaképtagok) és 0x4 (memóriakészlet munkasora).
Kapcsolódó témakörök