Synchronizace a překrývající se vstup a výstup
V souborech, pojmenovaných kanálech a sériových komunikačních zařízeních můžete provádět synchronní nebo asynchronní operace (označované také jako překrývající se) vstupně-výstupní operace. WriteFile, ReadFile, DeviceIoControl, WaitCommEvent, ConnectNamedPipea TransactNamedPipe lze provádět synchronně nebo asynchronně. Funkce ReadFileEx a WriteFileEx lze provádět pouze asynchronně.
Když se funkce provede synchronně, nevrací se, dokud se operace nedokončí. To znamená, že spuštění volajícího vlákna může být blokováno po neomezenou dobu, zatímco čeká na dokončení časově náročné operace. Funkce volané pro překrývající se operaci se můžou vrátit okamžitě, i když operace nebyla dokončena. To umožňuje, aby se na pozadí spustila časově náročná vstupně-výstupní operace, zatímco volající vlákno není možné provádět další úlohy. Jedno vlákno může například provádět souběžné vstupně-výstupní operace na různých popisovačích nebo dokonce souběžné operace čtení a zápisu na stejném úchytu.
K synchronizaci jeho provádění s dokončením překrývající se operace používá volající vlákno GetOverlappedResult funkce, GetOverlappedResultEx nebo jednu z čekací funkce určit, kdy se překrývající operace dokončila. K dotazování na dokončení můžete také použít makro HasOverlappedIoCompleted.
Pokud chcete zrušit všechny čekající asynchronní vstupně-výstupní operace, použijte funkci CancelIoEx a zadejte překrývající se strukturu, která určuje požadavek na zrušení. Pomocí funkce CancelIo zrušte čekající asynchronní vstupně-výstupní operace vydané volajícím vláknem pro zadaný popisovač souboru.
Překrývající se operace vyžadují soubor, pojmenovaný kanál nebo komunikační zařízení vytvořené pomocí příznaku FILE_FLAG_OVERLAPPED. Když vlákno volá funkci (například funkci ReadFile) k provedení překrývající se operace, volající vlákno musí zadat ukazatel na OVERLAPPED struktury. (Pokud je tento ukazatel null, může návratová hodnota funkce nesprávně znamenat, že operace byla dokončena.) Všechny členy PŘEKRÝVAJÍCÍ se struktury musí být inicializovány na nulu, pokud se událost nepoužije k signalizaci dokončení vstupně-výstupní operace. Pokud se použije událost, hEvent člen PŘEKRÝVAJÍCÍ se struktury určuje popisovač přiděleného objektu události. Systém nastaví stav objektu události na nepřiřazené, když volání vstupně-výstupní funkce vrátí před dokončením operace. Systém nastaví stav objektu události tak, aby signalizoval, když byla operace dokončena. Událost je nutná pouze v případě, že současně bude existovat více než jedna nevyřízených vstupně-výstupních operací. Pokud se událost nepoužívá, každá dokončená vstupně-výstupní operace bude signalizovat soubor, pojmenovaný kanál nebo komunikační zařízení.
Při zavolání funkce k provedení překrývající se operace může být dokončena před vrácením funkce. V takovém případě se výsledky zpracovávají, jako by se operace prováděla synchronně. Pokud však operace nebyla dokončena, návratová hodnota funkce je FALSEa funkce GetLastError vrátí ERROR_IO_PENDING.
Vlákno může spravovat překrývající se operace pomocí jedné ze dvou metod:
- Pomocí funkce GetOverlappedResult nebo GetOverlappedResultEx počkejte na dokončení překrývající se operace. Pokud se používá GetOverlappedResultEx, volající vlákno může určit časový limit pro překrývající se operaci nebo provést upozornění čekání.
- Zadejte popisovač objektu události PŘEKRÝVAJÍCÍ se struktury ručního resetování v jednom z čekací funkce a potom po vrácení funkce čekání volejte GetOverlappedResult nebo GetOverlappedResultEx. Funkce vrátí výsledky dokončené překrývající se operace a pro funkce, ve kterých jsou tyto informace vhodné, hlásí skutečný počet bajtů, které byly přeneseny.
Při provádění více souběžných překrývajících se operací v jednom vlákně musí volající vlákno zadat PŘEKRÝVAJÍCÍ se strukturu pro každou operaci. Každá překrývající se struktury musí určovat popisovač jiného objektu události ručního resetování. Chcete-li počkat na dokončení některé z překrývajících se operací, vlákno určuje všechny obslužné rutiny události ručního resetování jako kritéria čekání v jednom z více objektů čekací funkce. Návratová hodnota funkce čekání více objektů označuje, který objekt události ručního resetování byl signalován, takže vlákno může určit, která překrývající se operace způsobila dokončení operace čekání.
Pro každou překrývající se operaci je bezpečnější použít samostatný objekt události, nikoli určit žádný objekt události nebo znovu použít stejný objekt události pro více operací. Pokud není ve struktuře PŘEKRÝVAJÍCÍ se zadán žádný objekt události, systém po dokončení překrývající se operace signalizuje stav souboru, pojmenovaného kanálu nebo komunikačního zařízení. Proto můžete tyto popisovače zadat jako synchronizační objekty ve funkci čekání, jejich použití pro tento účel může být obtížné, protože při provádění souběžných překrývajících se operací na stejném souboru, pojmenovaném kanálu nebo komunikačním zařízení neexistuje způsob, jak zjistit, která operace způsobila signalizovat stav objektu.
Vlákno by nemělo opakovaně používat událost s předpokladem, že událost bude signalizovat pouze překrývající se operací daného vlákna. Událost je signalována ve stejném vlákně jako překrývající se operace, která se provádí. Použití stejné události na více vláknech může vést k konfliktu časování, ve kterém je událost signalizovaná správně pro vlákno, jehož operace se dokončí nejprve a předčasně pro jiná vlákna používající tuto událost. Po dokončení další překrývající se operace se událost znovu signalizují pro všechna vlákna, která tuto událost používají, a tak dále, dokud nebudou všechny překrývající se operace dokončeny.
Příklady, které ilustrují použití překrývajících se operací, rutin dokončení a funkce GetOverlappedResult, najdete v tématu Using Pipes.
Windows Vista, Windows Server 2003 a Windows XP:
Při opakovaném spuštění překrývající se struktury buďte opatrní. Pokud překrývající se struktury se znovu používají na více vláknech a GetOverlappedResult se volá s parametrem bWait nastaveným na TRUE, volající vlákno musí před opětovným použitím struktury zajistit, aby přidružená událost byla signalována. Toho lze dosáhnout pomocí funkce WaitForSingleObject po volání GetOverlappedResult vynutit, aby vlákno čekalo, dokud se operace nedokončí. Všimněte si, že objekt události musí být objekt události ručního resetování. Pokud se použije objekt události autoreset, volání GetOverlappedResult s parametrem bWa it nastaveným na TRUE způsobí, že funkce bude trvale blokovaná. Toto chování se změnilo od systémů Windows 7 a Windows Server 2008 R2 pro aplikace, které určují Systém Windows 7 jako podporovaný operační systém v manifestu aplikace. Další informace naleznete manifesty aplikace.
Související témata
-
koncepty vstupně-výstupních operací