4

select() 呼び出しを使用して、データを常に読み取る専用スレッドでシリアル ポート fd を無期限にブロックします。ただし、選択呼び出しからウェイクアップする方法がわかりません(タイムアウトなどを設定しない限り)。ソケットプログラミングでは、select() でブロックされたスレッドを起動するための shutdown() 呼び出しがあります。

ただし、シリアルポートを使用すると、アナログは表示されません。「リーダー」スレッドが select() でブロックされている間に別のスレッドから close() を呼び出すことは、POSIX で明確に定義された動作ではないようです。特に Linux では、fd で close() を呼び出しても、その fd で select() を呼び出したスレッドは起動しません。から ( http://linux.die.net/man/2/select ):

select() によって監視されているファイル記述子が別のスレッドで閉じられている場合、結果は規定されていません。一部の UNIX システムでは、select() はブロックを解除して戻り、ファイル記述子の準備ができていることを示します (select() が戻ってから実行されるまでの間に別のファイル記述子が再度開かれない限り、後続の I/O 操作はエラーで失敗する可能性があります)。 I/O 操作が実行されました)。Linux (およびその他のシステム) では、別のスレッドでファイル記述子を閉じても、select() には影響しません。要約すると、このシナリオで特定の動作に依存するアプリケーションは、バグがあると見なす必要があります。

Linux のシリアルポート fd で無期限にブロックされたスレッドをウェイクアップすることは可能ですか?

編集:

これを回避するには、sleep() を使用してループ内で select() を呼び出すという「ハック」的な方法があります (ただし、ウェイクアップ要求とスレッドが実際にウェイクアップする間に遅延があるため、これは理想的ではありません)。ループシステムで select を呼び出すことについて何か有害なことはありますか?

4

1 に答える 1

1

2 つの典型的なソリューション:

  1. パイプを作成し、選択キューに追加します。このパイプを介してデータを送信したらすぐに、終了を選択します。

  2. すべてのスレッドを起動しても問題ない場合は、シグナルを送信できます。

于 2013-10-08T21:50:03.817 に答える