Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Detekce zablokování monitoruje použití prostředků, které je potřeba zamknout – spin locky, mutexy a rychlé mutexy. Tato možnost Ověření ovladače rozpozná logiku kódu, která má potenciál způsobit zablokování v určitém budoucím bodě.
Možnost detekce vzájemného zablokování v Driver Verifier spolu s rozšířením ladicího programu jádra !deadlock je účinným nástrojem pro zajištění toho, aby se váš kód vyhnul nesprávnému použití těchto prostředků.
Detekce zablokování je podporována pouze v systému Windows XP a novějších verzích systému Windows.
Příčiny zablokování
Zablokování je způsobeno, když dojde ke sporu dvou nebo více vláken o některý prostředek takovým způsobem, že není možné provádět žádnou činnost.
Nejběžnější forma zablokování nastane, když dvě nebo více vláken čeká na prostředek, který vlastní druhé vlákno. To je znázorněno takto:
| Vlákno 1 | Vlákno 2 |
|---|---|
| Zamkne zámek A. | Přebírá zámek B |
| Zamčení žádostí B | Zamkne A |
Pokud k oběma sekvencí dojde současně, vlákno 1 nikdy nedostane Zámek B, protože je vlastněn vláknem 2 a vlákno 2 nikdy nedostane Zámek A, protože je vlastněn vláknem 1. V nejlepším případě to způsobí zastavení vláken a v nejhorším případě systém přestane reagovat.
Vzájemné zablokování se neomezuje jen na dvě vlákna a dva prostředky. Třísměrné vzájemné zablokování mezi třemi vlákny a třemi zámky se běžně vyskytují – a občas dochází i k pětidílné nebo šestidílné patové situaci. Tyto vzájemná zablokování vyžadují určitý stupeň "špatného štěstí", protože spoléhají na řadu věcí, které se dějí současně. Čím dál jsou od sebe získání zámků, tím pravděpodobnější je, že k těmto situacím dojde.
Zablokování jednoho vlákna může nastat, pokud se vlákno pokusí převzít zámek, který již vlastní.
Společný jmenovatel mezi všemi deadlocky je to, že hierarchie zámků se nerespektuje. Kdykoli je nutné mít najednou více než jeden zámek, měl by mít každý zámek jasnou prioritu. Pokud je A přijato dříve než B v jednom okamžiku a B před C v jiném, hierarchie je A-B-C. To znamená, že A nesmí být nikdy získán po B nebo C a B nesmí být získán po C.
Hierarchie zámků by se měla dodržovat i v případě, že neexistuje možnost deadlocku, protože během údržby kódu může být snadné neúmyslně zavést zablokování.
Prostředky, které můžou způsobit zablokování
Nejjednoznačnější zablokování jsou výsledkem vlastněných prostředků. Patří mezi ně spinové zámky, mutexy, rychlé mutexy a ERESOURCEs.
Prostředky, které jsou signalizované spíše než vlastněné (například události a porty LPC), tendují k tomu způsobit mnohem nejednoznačnější vzájemné zablokování. Je samozřejmě možné a bohužel také příliš běžné, že kód může zneužít tyto prostředky takovým způsobem, že dvě vlákna nakonec budou čekat na dokončení jednoho druhého do nekonečna. Vzhledem k tomu, že tyto prostředky nejsou ve vlastnictví žádného vlákna, není možné s jakoukoli jistotou identifikovat problémové vlákno.
Volba Detekce vzájemného zablokování v Driver Verifier hledá potenciální deadlocky zahrnující spin locky, mutexy a rychlé mutexy. Nemonitoruje použití ERESOURCE ani použití nevlastněných prostředků.
Účinky detekce vzájemného zablokování
Rutiny detekce zablokování ovladače najdou porušení hierarchie uzamčení, která nemusí být nutně současná. Ve většině případů tato porušení identifikují cesty kódu, které když dostanou příležitost, způsobí zablokování.
Aby bylo možné identifikovat potenciální zablokování, Driver Verifier sestaví graf pořadí získávání prostředků a hledá smyčky. Pokud byste měli vytvořit uzel pro každý prostředek a nakreslit šipku pokaždé, když se jeden zámek získá dříve než jiný, pak cykly představují porušení hierarchie zámků.
Driver Verifier vyvolá kontrolu chyb při zjištění některého z těchto porušení. K tomu dojde dříve, než dojde k nějakému skutečnému zablokování.
Poznámka:
I když se konfliktní cesty kódu nikdy nedají provést současně, měly by být přepsány i v případě, že zahrnují porušení hierarchie zámků. Takový kód je "zablokování čekající na uskutečnění", které by mohlo způsobit skutečné zablokování, pokud je kód mírně přepsán.
Když detekce deadlocku najde porušení, vyvolá kontrolu chyb 0xC4. První parametr této kontroly chyb bude indikovat přesné porušení. Mezi možná porušení patří:
Dva nebo více vláken zapojených do porušení hierarchie zámků
Vlákno, které se pokouší výhradně získat prostředek, jehož je již sdíleným vlastníkem (výhradně vlastněné prostředky lze získat sdíleně; sdílené prostředky nelze získat výhradně).
Vlákno, které se pokusí získat stejný prostředek dvakrát (samočinné zablokování)
Prostředek, který se uvolní, aniž by byl získán jako první
Prostředek, který je uvolněn jiným vláknem než tím, které ho získalo
Prostředek, který je inicializován více než jednou nebo není inicializován vůbec
Vlákno, které je odstraněno, i když stále vlastní prostředky
Počínaje Systémem Windows 7 může ověřovatel ovladačů předpovědět možné zablokování. Například při pokusu o použití stejné datové struktury KSPIN_LOCK jak jako běžný spinlock, tak i jako spinlock ve frontě zásobníku.
Podívejte se na Kontrolu chyb 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) pro seznam parametrů kontroly chyb.
Monitorování detekce vzájemného zablokování
Jakmile detekce vzájemného zablokování najde porušení, můžete rozšíření ladicího programu jádra !deadlock použít ke zkoumání přesného průběhu události. Může zobrazit topologii hierarchie zámků a zásobník volání pro každé vlákno v okamžiku, kdy byly zámky původně získány.
Existuje podrobný příklad rozšíření !deadlock a obecné informace o rozšíření ladicích programů v dokumentaci v balíčku Nástroje ladění pro Windows. Podrobnosti najdete v tématu Ladění systému Windows .
Aktivace této možnosti
Poznámka:
Tato možnost není kompatibilní se zpožděním synchronizace jádra.
Funkci detekce deadlocku můžete aktivovat pro jeden nebo více ovladačů pomocí Správce ověřování ovladačů nebo příkazové řádky Verifier.exe. Podrobnosti najdete v tématu Výběr možností ověření ovladače.
Na příkazovém řádku
Na příkazovém řádku je možnost Detekce zablokování reprezentována bitem 5 (0x20). K aktivaci detekce zablokování použijte hodnotu příznaku 0x20 nebo přidejte 0x20 k hodnotě příznaku. Například:
verifier /flags 0x20 /driver MyDriver.sysFunkce bude aktivní po dalším spuštění.
V systému Windows Vista a novějších verzích systému Windows můžete také aktivovat a deaktivovat detekci zablokování bez restartování počítače přidáním parametru /volatile do příkazu. Například:
verifier /volatile /flags 0x20 /adddriver MyDriver.sysToto nastavení je efektivní okamžitě, ale při vypnutí nebo restartování počítače dojde ke ztrátě. Podrobnosti najdete v tématu Použití volatile nastavení.
Funkce Detekce vzájemného zablokování je také součástí standardního nastavení. Například:
verifier /standard /driver MyDriver.sysPoužití Správce ověřovatele ovladačů
Vyberte Vytvořit vlastní nastavení (pro vývojáře kódu) a pak vyberte Další.
Vyberte jednotlivá nastavení z úplného seznamu.
Zaškrtněte detekci vzájemného zablokování.
Funkce Detekce vzájemného zablokování je také součástí standardního nastavení. Pokud chcete tuto funkci použít, vyberte ve Správci ověření ovladačemožnost Vytvořit standardní nastavení.