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.
Viz také ukázkové aplikace související s vstupně-výstupními operacemi.
Existují dva typy synchronizace vstupu a výstupu (V/V): synchronní vstupně-výstupní operace a asynchronní vstupně-výstupní operace. Asynchronní vstupně-výstupní operace se také označuje jako překrývající se vstupně-výstupní operace.
V synchronní vstupně-výstupnísouboru vlákno spustí vstupně-výstupní operaci a okamžitě přejde do stavu čekání, dokud se vstupně-výstupní požadavek nedokončí. Vlákno provádějící asynchronních vstupně-výstupních operací souboru odešle do jádra vstupně-výstupní požadavek voláním příslušné funkce. Pokud je požadavek přijat jádrem, volající vlákno pokračuje ve zpracování jiné úlohy, dokud jádro signalizuje vlákno, že vstupně-výstupní operace je dokončena. Potom přeruší aktuální úlohu a podle potřeby zpracuje data z operace vstupně-výstupní operace.
Dva typy synchronizace jsou znázorněny na následujícím obrázku.
V situacích, kdy se očekává, že požadavek na vstupně-výstupní operace trvá hodně času, například aktualizace nebo zálohování velké databáze nebo pomalého komunikačního propojení, je obecně dobrým způsobem optimalizace efektivity zpracování asynchronní vstupně-výstupní operace. U relativně rychlých vstupně-výstupních operací ale může být režie zpracování požadavků na vstupně-výstupní operace jádra a signály jádra méně přínosné, zejména pokud je potřeba provést mnoho rychlých vstupně-výstupních operací. V tomto případě by byl lepší synchronní vstupně-výstupní operace. Mechanismy a podrobnosti implementace těchto úloh se liší v závislosti na typu popisovače zařízení, který se používá, a konkrétních potřebách aplikace. Jinými slovy, obvykle existuje několik způsobů, jak tento problém vyřešit.
Synchronní a asynchronní informace o vstupně-výstupních operacích
Pokud je soubor nebo zařízení otevřené pro synchronní vstupně-výstupní operace (tj. není zadáno FILE_FLAG_OVERLAPPED ), následná volání funkcí, jako je WriteFile , může blokovat provádění volajícího vlákna, dokud nedojde k jedné z následujících událostí:
- Operace vstupně-výstupní operace se dokončí (v tomto příkladu zápis dat).
- Dojde k vstupně-výstupní chybě. (Například potrubí je uzavřeno od druhého konce.)
- V samotném volání došlo k chybě (například jeden nebo více parametrů není platný).
- Jiné vlákno v procesu volá funkci CancelSynchronousIo pomocí popisovače zablokovaného vlákna, čímž ukončí probíhající vstupně-výstupní operace pro toto vlákno, což způsobí selhání této vstupně-výstupní operace.
- Blokované vlákno je ukončeno systémem; Například samotný proces je ukončen nebo jiné vlákno volá funkci TerminateThread pomocí popisovače blokovaného vlákna. (Toto je obecně považováno za poslední možnost a není dobrý návrh aplikace.)
V některých případech může být toto zpoždění nepřijatelné pro návrh a účel aplikace, takže návrháři aplikací by měli zvážit použití asynchronních vstupně-výstupních operací s příslušnými objekty synchronizace vláken, jako jsou vstupně-výstupní porty dokončení. Další informace o synchronizaci vláken naleznete v tématu O synchronizaci.
Proces otevře soubor pro asynchronní vstupně-výstupní operace ve volání CreateFile zadáním příznaku FILE_FLAG_OVERLAPPED v parametru dwFlagsAndAttributes . Pokud není zadaný FILE_FLAG_OVERLAPPED, soubor se otevře pro synchronní vstupně-výstupní operace. Po otevření souboru pro asynchronní vstup a výstup se do volání ReadFile a WriteFile předá ukazatel na strukturu OVERLAPPED. Při provádění synchronních vstupně-výstupních operací se tato struktura nevyžaduje při volání ReadFile a WriteFile.
Poznámka
Pokud je soubor nebo zařízení otevřené pro asynchronní vstupně-výstupní operace, následná volání funkcí, jako je WriteFile , pomocí tohoto popisovače obvykle vrací okamžitě, ale může se také chovat synchronně s ohledem na blokované spuštění. Další informace naleznete v tématu asynchronní disk vstupně-výstupní operace se zobrazí jako synchronní ve Windows.
I když CreateFile je nejběžnější funkcí, která se používá pro otevírání souborů, svazků disků, anonymních kanálů a dalších podobných zařízení, lze také provádět vstupně-výstupní operace pomocí přetypovaného popisovače z jiných systémových objektů, jako je soket vytvořený funkcemisocket nebo accept.
Držitele objektů adresáře se získávají voláním funkce CreateFile s atributem FILE_FLAG_BACKUP_SEMANTICS. Popisovače adresářů se téměř nikdy nepoužívají – zálohovací aplikace jsou jednou z několika aplikací, které je obvykle používají.
Po otevření objektu souboru pro asynchronní I/O operace musí být struktura OVERLAPPED správně vytvořena, inicializována a předána do každého volání funkcí, jako je ReadFile a WriteFile. Při použití struktury OVERLAPPED v asynchronních operacích čtení a zápisu mějte na paměti následující skutečnosti:
- Neuvolňujte ani neupravujte OVERLAPPED strukturu ani datový buffer, dokud nejsou všechny asynchronní vstupně-výstupní operace pro objekt souboru dokončeny.
- Pokud deklarujete ukazatel na strukturu OVERLAPPED jako lokální proměnnou, neukončujte místní funkci, dokud nebudou dokončeny všechny asynchronní I/O operace na objektu souboru. Pokud dojde k předčasnému ukončení místní funkce, struktura OVERLAPPED vypadne z rozsahu a nebude přístupná žádným funkcím ReadFile nebo WriteFile, které potká mimo tuto funkci.
Můžete také vytvořit událost a umístit popisovač do struktury OVERLAPPED; čekací funkce je pak možné použít k čekání na dokončení vstupně-výstupní operace čekáním na popisovač události.
Jak už bylo uvedeno dříve, při práci s asynchronním popisovačem by aplikace měly při určování, kdy uvolnit prostředky přidružené k zadané vstupně-výstupní operaci na tomto popisovači. Pokud je popisovač předčasně uvolněn, ReadFile nebo WriteFile mohou nesprávně hlásit, že je vstupně-výstupní operace dokončena. Kromě toho funkce WriteFile někdy vrátí hodnotu TRUE s hodnotou GetLastErrorERROR_SUCCESS, i když používá asynchronní popisovač (který může také vrátit HODNOTU NEPRAVDA s ERROR_IO_PENDING). Programátoři zvyklí na synchronní vstupně-výstupní návrh obvykle uvolní prostředky vyrovnávací paměti dat v tomto okamžiku, protože TRUE a ERROR_SUCCESS označuje, že operace je dokončena. Pokud se ale porty pro dokončení vstupně-výstupních operací používají s tímto asynchronním popisovačem, paket dokončení se odešle i v případě, že se operace vstupně-výstupní operace dokončila okamžitě. Jinými slovy, pokud aplikace uvolní prostředky po WriteFile vrátí TRUE s ERROR_SUCCESS kromě rutiny portu pro doplňování vstupně-výstupních operací, bude mít dvojitou chybovou podmínku. V tomto příkladu doporučujeme, aby rutina portu dokončení byla zodpovědná výhradně za všechny operace uvolnění těchto prostředků.
Systém neudržuje ukazatel souboru na asynchronních popisovačích na soubory a zařízení, která podporují ukazatele souborů (tj. hledající zařízení), proto musí být pozice souboru předána funkcím čtení a zápisu v souvisejících posunových datových členech překrývající se struktury. Další informace naleznete v tématu WriteFile a ReadFile.
Umístění ukazatele souboru pro synchronní popisovač je udržováno systémem při čtení nebo zápisu dat a lze je aktualizovat také pomocí funkcí SetFilePointer nebo SetFilePointerEx.
Aplikace může také počkat na popisovač souboru, aby synchronizovala dokončení vstupně-výstupní operace, ale to vyžaduje extrémní opatrnost. Při každém spuštění vstupně-výstupní operace operační systém nastaví popisovač souboru na nepřiřazený stav. Při každém dokončení vstupně-výstupní operace operační systém nastaví popisovač souboru na signalovaný stav. Proto pokud aplikace spustí dvě vstupně-výstupní operace a čeká na popisovač souboru, neexistuje způsob, jak určit, která operace je dokončena, když je popisovač nastaven na signalovaný stav. Pokud aplikace musí v jednom souboru provádět více asynchronních vstupně-výstupních operací, měla by čekat na zpracování událostí v konkrétní struktuře OVERLAPPED pro každou vstupně-výstupní operaci, a ne na společném popisovači souborů.
Zrušení vstupně-výstupních operací
Pokud chcete zrušit všechny čekající asynchronní vstupně-výstupní operace, použijte jednu z těchto akcí:
- CancelIo: Tato funkce zruší pouze operace vydané volajícím vláknem pro zadaný popisovač souboru.
- CancelIoEx: Tato funkce zruší všechny operace vydané vlákny pro zadaný popisovač souboru.
Pomocí funkce CancelSynchronousIo zrušte čekající synchronní vstupně-výstupní operace.
Funkce ReadFileEx a WriteFileEx umožňují aplikaci určit rutinu, která se má provést (viz FileIOCompletionRoutine), když je dokončen asynchronní vstupně-výstupní požadavek.