Dela via


Synkronisering och överlappande indata och utdata

Du kan utföra antingen synkrona eller asynkrona (kallas även överlappade) I/O-åtgärder på filer, namngivna pipes och seriell kommunikationsenheter. Funktionerna WriteFile, ReadFile, DeviceIoControl, WaitCommEvent, ConnectNamedPipeoch TransactNamedPipe kan utföras synkront eller asynkront. Funktionerna ReadFileEx och WriteFileEx kan endast utföras asynkront.

När en funktion körs synkront returneras den inte förrän åtgärden har slutförts. Det innebär att körningen av den anropande tråden kan blockeras på obestämd tid medan den väntar på att en tidskrävande åtgärd ska slutföras. Funktioner som anropas för överlappande åtgärder kan returneras omedelbart, även om åtgärden inte har slutförts. Detta gör att en tidskrävande I/O-åtgärd kan köras i bakgrunden medan den anropande tråden kan utföra andra uppgifter. En enda tråd kan till exempel utföra samtidiga I/O-åtgärder på olika handtag, eller till och med samtidiga läs- och skrivåtgärder på samma handtag.

För att synkronisera körningen med den överlappande åtgärden använder den anropande tråden funktionen GetOverlappedResult, funktionen GetOverlappedResultEx eller någon av väntefunktioner för att avgöra när överlappningen har slutförts. Du kan också använda HasOverlappedIoCompleted makro för att avsöka efter slutförande.

Om du vill avbryta alla väntande asynkrona I/O-åtgärder använder du funktionen CancelIoEx och tillhandahåller en OVERLAPPED- struktur som anger vilken begäran som ska avbrytas. Använd funktionen CancelIo för att avbryta väntande asynkrona I/O-åtgärder som utfärdats av den anropande tråden för det angivna filhandtaget.

Överlappande åtgärder kräver en fil, namngiven pipe eller kommunikationsenhet som skapades med flaggan FILE_FLAG_OVERLAPPED. När en tråd anropar en funktion (till exempel funktionen ReadFile) för att utföra en överlappande åtgärd, måste den anropande tråden ange en pekare till en OVERLAPPED struktur. (Om den här pekaren är NULL-kan funktionens returvärde felaktigt indikera att åtgärden har slutförts.) Alla medlemmar i OVERLAPPED- struktur måste initieras till noll om inte en händelse används för att signalera slutförande av en I/O-åtgärd. Om en händelse används anger hEvent medlem i OVERLAPPED- struktur en referens till det allokerade händelseobjektet. Systemet anger tillståndet för händelseobjektet till nonsignaled när ett anrop till I/O-funktionen returneras innan åtgärden har slutförts. Systemet anger tillståndet för händelseobjektet till signalerat när åtgärden har slutförts. En händelse behövs bara om det finns fler än en utestående I/O-åtgärd samtidigt. Om en händelse inte används kommer varje slutförd I/O-åtgärd att signalera filen, namngivna pipe eller kommunikationsenheten.

När en funktion anropas för att utföra en överlappande åtgärd kan åtgärden slutföras innan funktionen returneras. När detta inträffar hanteras resultatet som om åtgärden hade utförts synkront. Om åtgärden inte slutfördes är funktionens returvärde FALSEoch funktionen GetLastError returnerar ERROR_IO_PENDING.

En tråd kan hantera överlappande åtgärder med någon av två metoder:

  • Använd funktionen GetOverlappedResult eller GetOverlappedResultEx för att vänta tills överlappande åtgärden har slutförts. Om GetOverlappedResultEx- används kan den anropande tråden ange en tidsgräns för överlappande åtgärd eller utföra en aviseringsbar väntan.
  • Ange ett handtag för OVERLAPPED--strukturens händelseobjekt för manuell återställning i någon av -väntefunktionerna och anropa sedan GetOverlappedResult eller GetOverlappedResultExnär väntefunktionen har returnerats. Funktionen returnerar resultatet av den slutförda överlappande åtgärden och för funktioner där sådan information är lämplig rapporterar den det faktiska antalet byte som överfördes.

När du utför flera samtidiga överlappande åtgärder på en enda tråd måste den anropande tråden ange en OVERLAPPED- struktur för varje åtgärd. Varje OVERLAPPED struktur måste ange ett handtag till ett annat händelseobjekt för manuell återställning. Om du vill vänta tills någon av de överlappande åtgärderna har slutförts anger tråden alla händelsereferenser för manuell återställning som väntevillkor i någon av funktionerna för väntefunktioner för flera objekt. Returvärdet för väntefunktionen för flera objekt anger vilket händelseobjekt för manuell återställning som signalerades, så att tråden kan avgöra vilken överlappande åtgärd som gjorde att vänteåtgärden slutfördes.

Det är säkrare att använda ett separat händelseobjekt för varje överlappande åtgärd i stället för att ange något händelseobjekt eller återanvända samma händelseobjekt för flera åtgärder. Om inget händelseobjekt anges i OVERLAPPED- struktur signalerar systemet tillståndet för filen, namngiven pipe eller kommunikationsenhet när den överlappande åtgärden har slutförts. Därför kan du ange dessa referenser som synkroniseringsobjekt i en väntefunktion, även om det kan vara svårt att hantera dem för detta ändamål, eftersom det inte finns något sätt att veta vilken åtgärd som orsakade att objektets tillstånd signalerades när de utförde samtidiga överlappande åtgärder på samma fil, namngivna pipe eller kommunikationsenhet.

En tråd bör inte återanvända en händelse med antagandet att händelsen endast signaleras av trådens överlappande åtgärd. En händelse signaleras på samma tråd som den överlappande åtgärden som slutförs. Att använda samma händelse på flera trådar kan leda till ett konkurrenstillstånd där händelsen signaleras korrekt för tråden vars åtgärd slutförs först och för tidigt för andra trådar som använder den händelsen. När nästa överlappande åtgärd är klar, signaleras händelsen sedan igen för alla trådar som använder händelsen och så vidare tills alla överlappande åtgärder har slutförts.

Exempel som illustrerar användningen av överlappande åtgärder, slutföranderutiner och funktionen GetOverlappedResult finns i Using Pipes.

Windows Vista, Windows Server 2003 och Windows XP:

Var försiktig när du återanvänder OVERLAPPED- strukturer. Om OVERLAPPED strukturer återanvänds på flera trådar och GetOverlappedResult anropas med parametern bWait inställd på TRUEmåste den anropande tråden se till att den associerade händelsen signaleras innan strukturen återanvänds. Detta kan åstadkommas med hjälp av funktionen WaitForSingleObject efter att ha anropat GetOverlappedResult för att tvinga tråden att vänta tills åtgärden har slutförts. Observera att händelseobjektet måste vara ett händelseobjekt för manuell återställning. Om ett händelseobjekt för automatisk reset används anropar GetOverlappedResult med parametern bWait inställd på TRUE gör att funktionen blockeras på obestämd tid. Det här beteendet ändrades från och med Windows 7 och Windows Server 2008 R2 för program som anger Windows 7 som det operativsystem som stöds i programmanifestet. Mer information finns i Programmanifest.

I/O-begrepp