3

私は Linux プログラミングは初めてで、すべての同期機能に完全に精通しているわけではないので、知識のある人にこの問題を解決する方法を尋ねたいと思います。

ループを実行したい単一のスレッドがあります。ループの停止ポイントは、ソケットでの読み取り操作です。読み取り操作を一定期間ブロックしてからタイムアウトさせたい。ただし、注意が必要なイベントがある場合は、読み取りからスレッドのブロックを解除する方法が必要です。「イベント」はさまざまなもののいずれかである可能性があるため、読み取りのブロックを解除する原因をスレッドに伝える何らかの方法が必要です。

ブロックされた読み取りをシグナルでブロック解除できることは知っていますが、それがどのように行われるかはわかりません。

4

5 に答える 5

3

ソケット操作のタイムアウトを設定できます。例:

struct timeval timeout;    
timeout.tv_sec = TIMEOUT_SEC;
timeout.tv_usec = TIMEOUT_MSEC;

setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

/* now receive msg */
recvmsg(sock_fd, &msg, 0);

ソケットをブロックしたい場合は、次のようにします。

timeout.tv_sec = 0;
timeout.tv_usec = 0;
setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
于 2013-08-09T15:41:50.377 に答える
2

epoll が進むべき道のようです:

epoll API は、poll(2) と同様のタスクを実行します。つまり、複数のファイル記述子を監視して、それらのいずれかで I/O が可能かどうかを確認します。epoll API は、エッジ トリガーまたはレベル トリガー インターフェイスのいずれかとして使用でき、多数の監視対象ファイル ディスクリプタに適切に対応します。epoll インスタンスを作成および管理するために、次のシステム コールが提供されます。

man epoll詳細については。マニュアルの「推奨される使用例」セクションを参照してください。

epoll と selectも参照してください

于 2013-08-09T14:58:10.973 に答える
1

他の人が言ったように使いたいように聞こえますselect()が、何らかの「メッセージ」が利用可能になったときにそれを中断する方法も必要です。a を中断する一般的な方法は、セルフ パイプ トリックselect()を使用することです。基本的に、pipe()を作成し、パイプの読み取りファイル記述子でも作成します。プログラムが管理するキューにメッセージが到着したら、パイプに 1 バイトを書き込みます。これにより、選択呼び出しが返され、パイプが読み取りの準備ができているかどうかを確認できます。その場合は、処理するメッセージがあることがわかっているので (それがコンテキスト内にあるものは何でも)、それを処理してからに戻ります。select()select(). さらに良いことに、パイプを実際にメッセージ キューにすることもできます。メッセージがキューにあることを通知する方法としてパイプを使用するだけの場合は、read()毎回実際にパイプからバイトを排出していることを確認してください。そうしないと、最終的にパイプがいっぱいになり、それ以上の通知を書き込むことができなくなります。

他の人が述べたように、1 つのスレッドがキューにサービスを提供し、ソケットへの書き込みを行い、別のスレッドが読み取りを行うのはなぜでしょうか? おそらくはるかに単純です。

于 2013-08-09T15:53:46.503 に答える
0

おそらく、次の 2 つのライブラリが役に立つかもしれません。

どちらも、1 つ以上のスレッドでイベント駆動型パラダイムを使用します (必要な場合)。もちろん、既に説明した API と条件変数を使用して独自のイベント駆動型フレームワークを実装することもできますが、それは必要以上の作業になる可能性があります。

于 2013-08-09T18:21:14.470 に答える