windows - overlappede I/O: Sådan vækker du en tråd på en færdiggørelsesport event eller en normal begivenhed?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil bruge en trådpulje til både at starte/annullere overlappede læseoperationer - ved hjælp af henholdsvis ReadFile() og CancelIo() - samt håndtere eventuelle afslutningsporthændelser, når læsningstransaktionerne er færdige.



  1. Enhver tråd kan starte en læseoperation

  2. Enhver tråd kan håndtere en afslutningsbegivenhed

  3. Kun den tråd, der startede en læsning, kan annullere den (dette er en begrænsning på CancelIo()



Jeg er ikke sikker på, hvordan man implementerer dette. Man kalder normalt GetQueuedCompletionStatus() for at afvente afslutningen af ​​porthændelser og WaitForSingleObject() for at vente på normale hændelser, men det er ikke klart, hvordan man blander de to. Hvis PostQueuedCompletionStatus() ville lade mig angive en bestemt tråd for at vågne op, blev jeg indstillet. Eventuelle ideer?


UPDATE : Løsningen skal køre på Windows XP. Desværre regner det ud med at bruge CancelIoEx() eller GetQueuedCompletionStatusEx().

Bedste reference


1 og 2 er nemme, brug kun IO Completion porten.


Men som du har fundet 3 kræver (før Windows V6 1 ) den samme tråd.


Hvis du bruger Windows>=V6, indeholder GetQueuedCompletionStatusEx en alternativ valgmulighed, som vil få den til at returnere, hvis der udføres en APC på tråden. Så brug QueueUserAPC til at køere en ikke-opdateret APC 1 , når du har brug for den pågældende tråd for at gøre noget andet arbejde. Du skal selvfølgelig have brug for en trådkæbekø for at give den afbrudte tråd instruktioner om, hvad du skal annullere. [13] [14]


Hvis tidligere version kompatibilitet er påkrævet, bliver tingene vanskeligere. Muligheder:



  • Brug parameteren timeout for GetQueuedCompletionStatus]] (http://msdn.microsoft.com/library/aa364986) for at vende tilbage regelmæssigt for at kontrollere, om der annulleres. [15]

  • Eller, muligvis mere praktisk, opdele trådpuljen i to grupper. Tråd, der starter og annullerer IO. Resten af ​​den tid, disse tråde bruger, venter på at blive signaleret til at udføre en af ​​disse handlinger. Den anden del af puljen venter på IO-afslutninger med GetQueuedCompletionStatus.



Ingen af ​​disse er så rart, men det er altid problemet med ældre versioner: de mangler funktionalitet.


1 Brug en ikke-APC i stedet for at gøre arbejde i APC, så begrænsningerne på, hvad der kan gøres i en APC, og dens arvelige problemer med samtidighed, bliver omgået. (Da en APC udføres på en tråd, holdes eventuelle låse, der holdes fast i APC'en, enhver beskyttet tilstand vil være vilkårligt inkonsekvent.)