問題タブ [overlapped-io]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
windows - I/O 完了ポートに CompletionKey があるのはなぜですか?
CreateIoCompletionPort関数の CompletionKey に関する MSDN からのコメント:
CompletionKey パラメーターを使用して、どの I/O 操作が完了したかをアプリケーションが追跡できるようにします。この値は、機能制御のために CreateIoCompletionPort によって使用されません。むしろ、I/O 完了ポートとの関連付け時に FileHandle パラメータで指定されたファイル ハンドルにアタッチされます。この完了キーは、ファイル ハンドルごとに一意である必要があり、内部完了キュー プロセス全体でファイル ハンドルに付随します。完了パケットが到着すると、GetQueuedCompletionStatus 関数呼び出しで返されます。CompletionKey パラメータは、PostQueuedCompletionStatus 関数によっても使用され、独自の特殊目的の完了パケットをキューに入れます。
上記の発言は私に疑問を残します。次のように拡張されたオーバーラップ構造でユーザー コンテキストをファイル ハンドルに関連付けることができるのに、CompletionKey を使用する理由は次のとおりです。
完了後に CONTAINING_RECORD マクロを介して取得しますか?
クール、私は CompletionKey がハンドルごとのコンテキストであり、拡張されたオーバーラップ構造が I/O ごとのものであると確信しています。しかし、そのような設計の背後にある哲学は何ですか? また、ユーザー コンテキストの観点から拡張されたオーバーラップ構造の代わりに、どのような状況で CompletionKey を使用する必要があるのでしょうか?
windows - ReadFileEx()オーバーラップI / Oが完了したことを確認するにはどうすればよいですか?
HasOverlappedIoCompleted()
ReadFileEx()
およびで開始された非同期I/Oでは機能しませんWriteFileEx()
。下部のコードスニペットはこれを示しています。この例でReadFileEx()
は、入力のないパイプから読み取るため、読み取りは完了しません。ただし、HasOverlappedIoCompleted()
TRUEを返します。呼び出しをオーバーラップに変更すると、ReadFile()
期待HasOverlappedIoCompleted()
どおりにFALSEが返されます。
私の質問は、コールバック自体に依存せずに、コールバックと重複したI / O要求が完了したかどうかを確認するにはどうすればよいですか?私のアプリケーションでは、APCはキューに入れられている可能性がありますが、アプリケーションがアラート可能な状態でまだ待機していない可能性があるため、必ずしも実行されている必要はありません。
ありがとう。
(GetOverlappedResult()は役に立ちません-TRUEも返します。)
もう少し背景:ReadFileEx()
問題を簡単に示すことができるため、私が使用している例では。私のアプリケーションではWriteFileEx()
、パイプインスタンスを繰り返し呼び出しています。前のメッセージWriteFileEx()
がまだ完了していない場合は、メッセージを送信するのではなくドロップする必要があります(同じパイプインスタンスに複数の保留中の書き込みがないようにする必要があります)が、前のメッセージがWriteFileEx()
完了している場合は、次のメッセージを開始する必要があります。完了コールバックはまだ実行されていません。
編集:問題のシナリオの説明
- スレッドはアラート可能状態になります(1つの読み取りAPCがキューに入れられます)。
- 読み取りAPCが開始されます。WriteFileEx()をキューに入れ、「書き込み保留」フラグを設定します。次に、ReadFileEx()をキューに入れます。
- メインスレッドが作業を開始します(アラート不可)。
- キューに入れられた読み取りが完了します。
- キューに入れられた書き込みが完了します(読み取り後)。
- メインスレッドはアラート状態になります。
- 読み取りAPCはキューの最初にあるため、最初に実行されます。「書き込み保留中」フラグを調べ、まだ設定されているため、書き込みをドロップします。実際、WriteFileEx()は完了しましたが、ReadFileEx()が最初に完了したため、まだAPCを呼び出していません。
カスタムの「書き込み保留」フラグをテストする代わりに、APCがまだ実行されていない場合でも、WriteFileEx()が実際に完了したかどうかをOSから確認したいと思います。
c++ - オーバーラップ IO を使用して送信者の IP アドレスを取得する
WSARecvFrom には、送信者の IP アドレスを返すためのパラメーターがあることを知っています。しかし、重複したioで使用すると、渡す変数が満たされません。
incomingAddressString は「204.204.204.204」に等しくなりました
何か不足していますか?
ありがとう
windows - ホスト名を IP アドレスに非同期的に解決するにはどうすればよいですか?
ホスト名を IP アドレスに非同期的に解決するにはどうすればよいですか? GetAddrInfoEx は、Windows 7 以前では重複した I/O をサポートしていません。
ネイティブ C++ を使用しています。
c++ - WIN32ソケットAPI:イベントベースの完了通知を使用したソケットでの送信/受信のキャンセル
オーバーラップ操作でソケットを使用して、イベントベースの完了通知を選択しました。2つのイベントがあります。1つはデータ用で、もう1つは長い送信/受信をキャンセルするためのものです。
次に、WSASendを呼び出します。
に続く
これは、通知された任意の1つのイベントに戻るように設定されています。ここで、送信が進行中であり、m_hInterruptEventが通知されたと仮定します。WSAWaitForMultipleEventsが戻ります。技術的には、sendを呼び出す関数も戻り、内部で割り当てられたバッファーを削除できます。
私にはわかりませんが、WSASendはまだバックグラウンドで動作している可能性があり、バッファを削除すると、最良の場合、データが破損します。
ソケットを他の何かにすぐに使用する必要がある場合、バックグラウンドの送信/受信を停止する適切な方法は何でしょうか?
CancelIO()を見ましたが、MSDNはSocketsに関連して言及していません。ファイルベースのIOでのみ機能しますか?
winapi - イベント トリガー ウィンドウ メッセージ
イベントが設定されているときにウィンドウ メッセージを生成する方法はありますか? 重複した I/O 操作をセットアップしたいので、ブロックされませんが、そのステータスをポーリングしたくありません。スレッドを使用できることはわかっていますが、この操作にのみ必要です。もっと良い方法があるようです。
windows - Windows での潜在的な種類の非同期 (オーバーラップ) I/O 実装
これを実装するには多くの方法があるため、Windows での潜在的な種類の非同期 (オーバーラップ) I/O 実装について説明したいと思います。Windows のオーバーラップ I/O は、データを非同期的に処理する機能を提供します。つまり、操作の実行はノンブロッキングです。
編集:この質問の目的は、一方では私自身の実装の改善について議論し、他方では代替実装について議論することです。どの非同期 I/O 実装が並列の重い I/O で最も理にかなっており、ほとんどがシングル スレッドの小さなアプリケーションで最も理にかなっています。
MSDNを引用します:
関数が同期的に実行されると、操作が完了するまで戻りません。これは、時間のかかる操作が終了するのを待っている間、呼び出し元のスレッドの実行が無期限にブロックされる可能性があることを意味します。オーバーラップ操作のために呼び出された関数は、操作が完了していなくても、すぐに戻ることができます。これにより、時間のかかる I/O 操作をバックグラウンドで実行できるようになり、呼び出し元のスレッドは自由に他のタスクを実行できます。たとえば、単一のスレッドは、異なるハンドルで同時 I/O 操作を実行したり、同じハンドルで同時の読み取り操作と書き込み操作を実行したりすることもできます。
読者はオーバーラップ I/O の基本概念に精通していることを前提としています。
非同期 I/O のもう 1 つの解決策は完了ポートですが、これはこの説明の主題ではありません。その他の I/O 概念の詳細については、MSDN の「ファイル管理について > 入力および出力 (I/O) > I/O の概念」を参照してください。
ここで私の (C/C++) 実装を紹介し、議論のために共有したいと思います。
これは、拡張された OVERLAPPED 構造体で、次のように呼ばれIoOperation
ます。
ReadFile
この構造体は、 orのような非同期操作WriteFile
が呼び出されるたびに作成されます。フィールドは、Handle
対応するデバイス/ファイル ハンドルで初期化されます。Operation
どの操作が呼び出されたかを示すユーザー定義フィールドです。フィールドBuffer
は、指定された size で以前に割り当てられたメモリのチャンクへのポインタBufferSize
です。もちろん、この構造体は自由に展開できます。操作結果、実際に転送されたサイズなどを含めることができます。
最初に必要なのは、重複した I/O が完了するたびに通知される (自動リセット) イベント ハンドルです。
最初に、すべての非同期操作に対して 1 つのイベントのみを使用することにしました。次に、このイベントを RegisterWaitForSingleObject を使用してスレッド プール スレッドに登録することにしました。
したがって、このイベントが通知されるたびに、コールバックWaitOrTimerCallback
が呼び出されます。
非同期操作は次のように初期化されます。
各操作はキューに入れられGetOverlappedResult
、コールバックでの呼び出しが成功した後に削除されWaitOrTimerCallback
ます。new
ここで常に呼び出す代わりに、メモリプールを使用してメモリの断片化を回避し、割り当てを高速化できます。
もちろん、マルチスレッドを安全に行うには、たとえば I/O キューにアクセスするときにロック保護 (クリティカル セクション) が必要です。
この種の実装には利点もありますが、欠点もあります。
利点:
- 永続的なスレッド プール スレッドでの実行。手動でスレッドを作成する必要はありません
- 必要なイベントは 1 つだけです
- 各操作は I/O キューに入れられます (CancelIoEx は後で呼び出すことができます)
短所:
- I/O キューには余分なメモリ/CPU 時間が必要です
- GetOverlappedResult は、キューに入れられたすべての I/O に対して、未完了のものも含めて呼び出されます
c++ - I/Oが重複しているノンブロッキングソケット
私はソケットジャングルを通り抜けようとしていますが、I/Oが重複しているノンブロッキングソケットに出くわしました。私は家に3冊の本を持っていますが、それはこの概念についてのみ言及していますが、実際にはそれを説明したり、例を挙げたりしていません。
だから私が探しているのは、これが例で説明されている記事、または私が自分で取り組むことができる単なる例です。これがWindows用であればいいのですが、UNIXからも転送できるはずです。
私は本を出典として気にしませんが、さらに50ドルを避けて喜んでいます。これまでのところ、私は非常に基本的な概念と他のソケットモデルとの基本的な比較しか見つけませんでした。彼らのコンセプトがわからないということではありませんが、彼らの行動を見て、彼らがどのように機能するかについての良い説明を得たいと思います。(私は長い記事をまったく気にしません:))
c++ - c++ D'tor とのオーバーラップ I/O 競合の使用
クライアントのリクエストを解釈し、適切なハンドラーをディスパッチするメインループを持つ単一クライアントの(今のところ)サーバーを作成しています。
いくつかのタスクでは、MS オーバーラップ I/O を使用したいと思います (これは Windows 専用です)。そのうちの 1 つで、ファイルから読み取り、コンテンツをソケットに書き込みたいと考えています。私はそのアクションのためにクラスラップを持っているので、それはバッファ、ファイルのサイズを割り当て、次にReadFileへの呼び出し(実際のファイルシステムファイルを使用)が行われ、その後にWriteFileが続きます(今回はソケットハンドルへ) )両方が重なって作られています。
問題は: 非同期であるため、クラス d'tor が自動的に呼び出され、ジョブが完了する前にファイルのバッファーが解放されます。
明らかに、それは私の壊れたデザインです。あなたの提案を聞きたいです。
ありがとう!
linux - Linuxには本当に非同期ブロックI/Oはありませんか?
CPUにバインドされているが、高性能I/O要件もあるアプリケーションについて考えてみます。
LinuxファイルI/OをWindowsと比較していますが、epollがLinuxプログラムにどのように役立つかはまったくわかりません。カーネルは、ファイル記述子が「読み取る準備ができている」ことを通知しますが、データを取得するには、blocking read()を呼び出す必要があります。メガバイトを読み取りたい場合は、それがブロックされることは明らかです。
Windowsでは、OVERLAPPEDが設定されたファイルハンドルを作成し、ノンブロッキングI / Oを使用して、I / Oが完了したときに通知を受け取り、その完了関数からのデータを使用できます。データを待つためにアプリケーションレベルの実時間を費やす必要はありません。つまり、スレッドの数をコアの数に正確に調整し、100%効率的なCPU使用率を得ることができます。
Linuxで非同期I/Oをエミュレートする必要がある場合は、これを行うためにいくつかのスレッドを割り当てる必要があります。これらのスレッドは、CPUの処理に少し時間を費やし、I/Oのブロックに多くの時間を費やします。さらに、これらのスレッドとの間のメッセージングにオーバーヘッドが発生します。したがって、CPUコアを過剰にサブスクライブするか、十分に活用しません。
mmap()+ madvise()(WILLNEED)を「貧乏人の非同期I / O」と見なしましたが、完了したときに通知を受け取ることができないため、まだそこまで到達していません。 「推測」し、「間違っている」と推測すると、メモリアクセスがブロックされ、ディスクからデータが送信されるのを待ちます。
Linuxはio_submitで非同期I/Oを開始しているようで、ユーザースペースのPOSIX aio実装もあるようですが、しばらくの間そのようになっており、これらのシステムを批判的に保証する人は誰もいません。 、高性能アプリケーション。
Windowsモデルはおおよそ次のように機能します。
- 非同期操作を発行します。
- 非同期操作を特定のI/O完了ポートに関連付けます。
- そのポートで操作が完了するのを待ちます
- I / Oが完了すると、ポートで待機しているスレッドはブロックを解除し、保留中のI/O操作への参照を返します。
ステップ1/2は通常、1つのこととして実行されます。ステップ3/4は通常、I / Oを発行するのと同じスレッドではなく、(必然的に)ワーカースレッドのプールを使用して実行されます。このモデルは、boost :: asioが提供するモデルと多少似ていますが、boost :: asioが実際には非同期のブロックベース(ディスク)I/Oを提供しない点が異なります。
Linuxでのepollとの違いは、ステップ4ではI / Oがまだ発生していないことです。ステップ1は、ステップ4の後に続きます。これは、必要なものが正確にわかっている場合は「逆方向」です。
多数の組み込み、デスクトップ、およびサーバーオペレーティングシステムをプログラムしたので、この非同期I / Oのモデルは、特定の種類のプログラムにとって非常に自然であると言えます。また、非常に高スループットで低オーバーヘッドです。これは、APIレベルでのLinux I/Oモデルの残りの本当の欠点の1つだと思います。