1

スレッドプールを使用して、重複した読み取り操作を開始/キャンセルします(それぞれを使用してReadFile()) 。またCancelIo()、読み取り操作が完了したときに完了ポートイベントを処理します。

  1. どのスレッドでも読み取り操作を開始できます
  2. どのスレッドも読み取り完了イベントを処理できます
  3. 読み取りを開始したスレッドのみがそれをキャンセルできます(これはCancelIo()制限です)

これを実装する方法がわかりません。GetQueuedCompletionStatus()通常、完了ポートイベントを待機し、通常のイベントを待機するように呼び出しWaitForSingleObject()ますが、この2つを組み合わせる方法は明確ではありません。PostQueuedCompletionStatus()ウェイクアップする特定のスレッドを指定できるとしたら、設定されます。何か案は?

更新:ソリューションはWindowsXPで実行する必要があります。残念ながら、これはまたはの使用を除外しCancelIoEx()ますGetQueuedCompletionStatusEx()

4

1 に答える 1

4

1と2は簡単で、IO完了ポートを使用するだけです。

ただし、3つは(Windows V6 1より前の)同じスレッドを必要とすることがわかったように。

Windows> = V6を使用している場合GetQueuedCompletionStatusExは、スレッドでAPCが実行されたときに戻るようにする変更可能なオプションが含まれています。したがって、他の作業を行うために特定のスレッドが必要な場合は、no -QueueUserAPC opAPC1をキューに入れるために使用します。もちろん、中断されたスレッドにキャンセルする内容を提供するために、スレッドセーフキューが必要になります。

以前のバージョンの互換性が必要な場合は、事態はさらに困難になります。可能性:

  • GetQueuedCompletionStatus](http://msdn.microsoft.com/library/aa364986 )のタイムアウトパラメータを使用して定期的に戻り、キャンセルを確認します。

  • または、おそらくもっと実際的には、スレッドプールを2つのグループに分割します。IOを開始およびキャンセルするスレッド。これらのスレッドがこれらのアクションの1つを実行するように通知されるのを待つために費やす残りの時間。プールの他の部分は、でIOの完了を待機しGetQueuedCompletionStatusます。

これらはどちらも素晴らしいものではありませんが、古いバージョンでは常に問題になります。機能が不足しています。

1 APCで作業を行うのではなく、no-op APCを使用して、APCで実行できることの制限と、並行性に関する固有の問題を回避します。(APCはスレッドで実行されるため、スレッドが保持するロックはAPCで保持されるため、保護される状態は任意に矛盾します。)

于 2009-06-07T10:17:38.023 に答える