2016-10-28 11 views
1

デバイス/ファイル記述子からブロックされた方法で読み取り中です。 異なるスレッドでデバイスが閉じられ、ファイル記述子が削除されることがあります。残念ながら、読んでも返ったり通知を受けたりしてブロックされません。C:ファイル記述子が削除された場合、ブロック読み取りが返されます。

回避策として、選択をタイムアウトとしてwhileループを実行できます。タイムアウトが発生した場合、私はファイル記述子をチェックすることができます。

Linux-Cでもっと良い方法があるのでしょうか?

+0

"*私はファイル記述子を確認できます*"何を確認してください? – alk

+0

"* ... filedescriptorは削除されます*" "ファイルディスクリプタはどのように" * deleted * "にできますか? – alk

+0

@MarekKlein:ファイル記述子がすでにclose()に渡されていて、別のスレッドである間に "リサイクル"されていなかった場合、読み込みは失敗し、-1を返します。必ずしも ' EOF'。 – alk

答えて

2

あなたが記述されているコードは、固有の競合状態を持っている - 別のスレッドがときにclose()そのファイルディスクリプタファイルディスクリプタにread()をブロックであることができれば、他のスレッドは、同じようにうまく代わりread()を呼び出すためにちょうど約ある可能性があります。

他のすべてのスレッドがそのファイル記述子をまったく使用する位置にないことが分かっていない限り、close()を呼び出すことはできません。

あなたが説明したようなケースを扱う最も簡単な方法は、あるスレッドが各ファイル記述子の「所有」スレッドになり、ファイル記述子を閉じることです。他のスレッドは直接ファイルをクローズしません。代わりに、ファイル記述子を共有データ構造の中で「閉じる」とマークし、所有スレッドを起動します。セットの中だけでなく、対象のファイルディスクリプタ - 通常パイプ -

あなたはそれが可能それがread()にブロックではなく、別のファイルディスクリプタにselect()またはpoll()にブロックしないことによって所有するスレッドをウェイクすることができます。スレッドは、そのパイプのもう一方の端に書き込むことによって呼び起こされます。

+0

私はそれのようなものを持っています。 1つのメインスレッド、デバイスのオープン、メモリの割り当て...、および処理が完了すると、同じclose関数が呼び出されます。しかし、あなたが正しいです、閉じて、別のスレッドで読んで終了するより良い私は最初に読んで終了する必要がありますと閉じるファイル記述子よりも。最初に説明したように(ループ、この変数のチェック、選択、読み込み)、simularで動作するものすべて。私はこれがあなたが意味するものだと思いますか? – Arno

+0

@ user3392481:はい、ファイル記述子を読み込んでいるスレッドが、フラグが設定されていることを確認したら、それを閉じるためのスレッドである方がずっと簡単です(そうでなければ、 mutexと条件変数によって保護された参照カウントのようなファイル記述子で終了します)。 – caf

2

ファイル記述子が他のスレッドによって閉じられると、それが起こったことを確認することは容易ではありません。他のスレッドがファイルを再オープンし、ファイル記述子が同じ の場合はどうなりますか?成功したclose()呼び出しでは、ファイル記述子に再度アクセスすることはできません。は未定義です。です。 close()コールが失敗した場合、POSIXはファイル記述子の状態をそのまま残します。unspecified

select()オプションは上記と同じです。

問題は、マルチスレッドプログラムの他のdata raceの問題とはまったく異なるものではありません。 コードを書き直して、スレッドが同期せずにファイル記述子にアクセスしないようにすることをお勧めします。あるいは、可能であれば、同じファイル記述子から読み取る複数のスレッドを避けてください。

+0

ああ、これは分かれています。あなたがすべてのスレッドを閉じることを確実にしたいと思うapplictaionの最後にあり、この読書はあきらめないでしょう。 – Arno

関連する問題