問題タブ [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.
delphi - オーバーラップI/O操作中のシリアルポートと処理エラー
最近シリアル通信を行っているので、読み取りや書き込みなどを行うすべてのWindowsAPI関数へのシンプルなインターフェイスであるクラスを用意しました。このクラス内のすべてのI/O操作は非同期で処理されます。
質問に進む前に、シリアルポートからデータを読み書きする方法を紹介します(書き込み機能はまったく同じで、両方を表示しても意味がないため、これは読み取り機能のみです)。 。
この関数が読み取り操作の終了を待機しているときに、重複する操作のためにシリアルポートを開く理由を尋ねる前に、ここで説明します。この方法でシリアルポートを開く場合にのみ、WaitCommEvent()メソッドがイベントを待機する時間を指定できます。重複しない操作のためにポートを開いた場合、WaitCommEvent()は、シリアルポートにイベントが表示されるまでブロックします。これは常に発生するとは限らず、呼び出し元のスレッドが永久にブロックされます。
それでも、上記のRead()関数に集中しましょう。
1)まず、イベントが設定されるのを時間制限なしで待ちます。そのため、現在のスレッドが何らかの理由で永久にブロックされる可能性はありますか?読み取り操作を非同期で実行するスレッドによってイベントが遅かれ早かれ設定されることを100%確信できるかどうかはわかりません。シリアルポートの読み取りタイムアウトがすべてゼロに設定されている場合、指定されたバイト数が読み取られるまで読み取り操作は終了しないことを知っていますが、これは私が知っている動作です。私の質問は、イベントが設定されず、WaitFor()メソッドが永久に待機する原因となる予期しない状況に関するものです-それは起こりそうですか?
2)WaitFor()は、待機操作中にエラーが発生したことを通知するwrErrorを返す場合があります(ただし、これは重複読み取り操作とはまったく関係ありませんよね?)。したがって、読み取り操作が終了するのを待つ必要はないと思います。イベントハンドルが使用できなくなる可能性があるからです。そこで、CancelIO()メソッドを呼び出して読み取り操作をキャンセルし、キャンセルされた読み取りを非同期的に実行するスレッドによってイベントが設定されるのを待ってから、例外を発生させます。Read()メソッドをすぐに(I / Oをキャンセルせずに)終了すると、そのスレッドがそのデータ(オーバーラップしたレコードデータ)をローカル変数に書き込むため、そのスレッドによって読み取りがキャンセルされるのを待ちます。その時はもう有効ではありませんよね?一方で、
上記の内容が正しいかどうか教えていただければ幸いです。コメントをお願いします。
事前にどうもありがとうございました。
c# - プロセス間での非同期IO
全て:
私はロギングソリューションを書いています。使用可能なログエンドポイントの1つは、テキストファイルです。複数のプロセスからそのファイルに書き込みたいと仮定します。共有でファイルを開き、名前付きミューテックスを使用してファイルへの同時アクセスを制御できます(すべてのアクセスが同じマシンで発生したと仮定します)。しかし、それから私は非同期IOについて疑問に思い始めました。プロセス内で、BeginWriteを使用して非同期で書き込みを発行できます。クロスプロセス、またはクロスマシンの問題はどうですか?そのような状況で非同期IOは安全ですか?
(BeginWrite()を呼び出すときに、渡すバッファーに、1つの論理「レコード」にまとめておく必要のあるすべてのものが含まれていると仮定します)
c# - 名前付きパイプ-非同期ピーク
非同期モードで開かれたSystem.IO.Pipe.NamedPipeServerStreamに、より多くのデータを読み取ることができる場合に通知を受ける方法を見つける必要があります。WaitHandleが理想的です。パイプに書き込みたい別のスレッドからシグナルが送信される可能性があるため、BeginRead()を使用してそのようなハンドルを取得することはできません。そのため、パイプのロックを解除して、書き込みが完了するのを待つ必要があります。 NamedPipeServerStreamにはCancelAsyncメソッドがありません。また、BeginRead()を呼び出してから、スレッドが通知された場合にパイプでwin32関数CancelIOを呼び出してみましたが、データが到着して処理されているときにCancelIOが呼び出された場合、これは理想的な解決策ではないと思います。ドロップされます-私はまだこのデータを保持したいのですが、書き込み後に後で処理します。
上記のテキストが少し不明瞭なリクレイイベントでは、これが私ができることを大まかに示しています...
c# - C#とネイティブのオーバーラップI / O
C#から呼び出すことができるようにラップしているCdllがあります。1つの関数は、イベントを使用して状態が変化したときに通知しますが、それに対処するためにいくつかの調査が必要でした。うまく機能しているようですが、誰かが私よりもこれについての経験があり、アドバイスを提供できるかどうか知りたいです。
この関数は、dllの.hファイルで次のように定義されています。
それを呼び出すサンプルCコード:
これは私がC#でそれにアプローチした方法です:
私がはっきりしないことの1つは、userDataの必要性です。NotifyStateChangeはイベントを発生させるだけで、データを返しません。nullのuserDataをPack()に渡すことは問題なく機能しているように見えましたが、私が気付いていない内部でuserDataで何かが起こっているのではないかと心配しています。
これを行うためのより適切な方法があるかどうかについてのアドバイスに感謝します。
エリック
asynchronous - WinUSB 非同期コントロール転送のキャンセル
WinUSB を使用するユーザー アプリケーション (ドライバーではない) の場合、WinUsb_ControlTransfer をオーバーラップ I/O と組み合わせて使用し、制御メッセージを非同期に送信します。非同期操作をキャンセルすることはできますか? WinUsb_AbortPipe は他のすべてのエンドポイントで機能しますが、コントロール エンドポイント (パイプ アドレスとして 0x00 または 0x80) が渡されると、「無効なパラメーター」エラーが発生します。CancelIo と CancelIoEx も試しましたが、どちらも WinUSB ハンドルで「無効なハンドル」エラーが発生します。私が見つけた唯一の関連情報はhttp://www.winvistatips.com/winusb-bugchecks-t335323.htmlにありますが、解決策はありません。これは単に不可能ですか?
file-io - ネットワーク ドライブ上のファイル全体をすばやく読み取る (Windows、C/C++、C# など)
最近、ネットワーク ドライブ上の大きなファイルの読み取りに問題があり、何が間違っているのか特定できません。私は C++ (アンマネージ) と C# の両方で試しましたが、両方でほぼ同じパフォーマンスでした...これはややひどいものでした。
ネットワーク上で 4 KB/秒のファイルを読み取ることもありますが、このファイルがローカル HD にある場合は、HD が出力できる最大データ レートを簡単に達成できます。それは、一度に 64 KB のチャンクを読み取ることです...私は非常識な数まで、またはそれ以下の大きなバッファで試しましたが、大きな違いはありません。
FileStream で BeginRead を使用して C# で非同期 IO を試し、C++ で OVERLAPPED IO と同期読み取りを試しましたが、すべて同じ問題があり、ネットワーク上で低速になっています。
私たちが思いついた唯一の解決策は、実際にファイルを読み取る前に、OS の CopyFile 機能を使用してローカル HD にファイルをコピーすることですが、この方法にはあまり満足していません。CopyFile が私たちとは違うことをしているように見えるだけで、私たちのアプローチよりも信じられないほど高速です。
これがなぜなのか、誰にも手がかりがありますか?
winapi - MSDN ReadFile() によると、Win32 関数は読み取り操作の完了を誤って報告する場合があります。いつ?
MSDN は、ReadFile()
機能の説明で次のように述べています。
hFile が で開かれる場合
FILE_FLAG_OVERLAPPED
、lpOverlapped パラメータは有効で一意の構造体を指す必要がありますOVERLAPPED
。そうしないと、関数が読み取り操作が完了したと誤って報告する可能性があります。
上記の推奨事項に違反しているアプリケーションがいくつかあり、問題の深刻度を知りたいです。つまり、プログラムは で作成された名前付きパイプをFILE_FLAG_OVERLAPPED
使用しますが、次の呼び出しを使用してそこから読み取ります。
つまりNULL
、パラメーターとして渡されlpOverlapped
ます。ドキュメントによると、その呼び出しは状況によっては正しく機能しないはずです。問題を再現するために多くの時間を費やしましたが、再現できませんでした! 私は常にすべてのデータを適切な場所に適切なタイミングで取得しました。ただし、名前付きパイプのみをテストしていました。
ReadFile() が誤って返され、データがまだバッファにない場合でも正常に完了したことを報告することを期待できるのはいつですか? 問題を再現するにはどうすればよいですか? ファイル、パイプ、ソケット、コンソール、またはその他のデバイスで発生しますか? 特定のバージョンの OS を使用する必要がありますか? または特定のバージョンの読み取り (ハンドルを I/O 完了ポートに登録するなど)? または、プロセス/スレッドの読み取りと書き込みの特定の同期?
または、いつ失敗しますか?わたしにはできる :/
助けてください!
よろしく、 マーティン
winapi - 同期 I/O 用に開かれた HANDLE を、存続期間中に非同期 I/O 用に開くように変更することはできますか?
Windows での私の日常的なプログラミング作業のほとんどは、現在、あらゆる種類の I/O 操作 (パイプ、コンソール、ファイル、ソケットなど) に関するものです。私は、さまざまな種類のハンドル (同期、非同期、イベントの完了待ち、ファイル HANDLE、I/O 完了ポート、アラート可能 I/O の待機) からの読み取りと書き込みのさまざまな方法をよく知っています。私たちはそれらの多くを使用しています。
一部のアプリケーションでは、すべてのハンドルを 1 つの方法で処理できると非常に便利です。つまり、プログラムは、受け取ったハンドルの種類を認識していない可能性があり、たとえば、すべての I/O 完了ポートを使用したいと考えています。
だから最初に私は尋ねます:
私がハンドルを持っているとしましょう:
これは、どこかからの I/O のプロセスによって受信されました。作成されたフラグを簡単かつ確実に確認する方法はありますか? 問題の主なフラグはFILE_FLAG_OVERLAPPED
.
これまでのところ、私が知っている唯一の方法は、そのようなハンドルを I/O 完了ポートに登録しようとすることです (を使用CreateIoCompletionPort()
)。それが成功した場合、ハンドルは FILE_FLAG_OVERLAPPED で作成されています。HANDLE
h
ただし、I/O 完了ポートのみを使用する必要があります。これは、ハンドル自体を閉じないとハンドルから登録を解除できないためです。
の存在を判断する簡単な方法がFILE_FLAG_OVERLAPPED
あるとすれば、次の 2 番目の質問があります。
そのようなフラグを既存のハンドルに追加する方法はありますか? これにより、同期操作用に最初に開いていたハンドルが、非同期操作用に開かれます。反対の方法を作成する方法はありますか (FILE_FLAG_OVERLAPPED
非同期から同期ハンドルを作成するために削除します)?
MSDN を読み、何度もグーグル検索した後も、直接的な方法は見つかりませんでした。同じことができる少なくともいくつかのトリックはありますか?CreateFile()
関数などを使用して同じ方法でハンドルを再作成するようなものですか? 部分的に文書化されているか、まったく文書化されていないものですか?
私がこれを必要とする主な場所は、プロセスがサードパーティのアプリケーションによって送信されたハンドルから読み取り/書き込みを行う方法を決定する (または方法を変更する) ことです。サードパーティ製品がハンドルを作成する方法を制御することはできません。
親愛なる Windows の達人: 助けてください!
よろしく
マーティン
windows - OVERLAPPED Win32 構造体の hEvent メンバー
非同期 I/O (または Win32 用語で「オーバーラップ」I/O) が使用される場合、OVERLAPPED
構造体とそのhEvent
メンバーを処理する必要があります。I/O 関数が読み取りまたは書き込み操作を遅らせる場合は、ERROR_IO_PENDING
エラー コードが返され、非同期操作が関数で完了するのを待ってから、WaitForXxxEvent
を呼び出しますGetOverlappedResult
。
ただし、I/O 操作がすぐに完了すると、 は取得されずERROR_IO_PENDING
、読み取り操作では読み取りバッファーがすぐにいっぱいになります。しかし、OVERLAPPED::hEvent
メンバーはどうですか?シグナル状態に設定されますか? それについての明確な声明は見つかりませんでした。
この質問は無意味に思えるかもしれません (操作が既に完了していることがわかっているのに、なぜイベントに対処する必要があるのでしょうか)。
edgar.holleisのコメントで指摘されているように、Raymond Chenはブログで次のように説明しています。
非同期 I/O が同期的に完了する場合、OVERLAPPED 構造体の hEvent はとにかく通知されますか?
はい。
I/O が (同期的または非同期的に) 完了すると、イベントが通知され、完了ステータス通知がキューに入れられます。この
GetOverlappedResult/Ex
関数は、すでに完了した I/O を待機するために使用できます。すぐに戻るだけです。I/O が完了したかどうかを HasOverlappedIoCompleted に問い合わせると、I/O が同期的に完了した場合、「もちろん、完了しました。かなり前に完了しました!」と正しく報告されます。つまり、非同期 I/O 要求が同期的に完了する場合は、あたかも非同期で完了したかのように論理的に扱うことができます。まばたきする前に、非同期に完了します。