2

select() を使用して、他のサーバーから更新を受信し、定期的なメッセージを送信したいと考えています。次の設定を検討してください。

while(1){ select(... タイムアウト = 5 秒); // 他のコード}

t = 2秒で更新を受信すると、 select()が返され、対応するステートメントが実行されます。次のループが始まると、タイムアウトは再び 5 秒に設定されます。ただし、 5 - 2 = 3秒にする必要があります。タイマーを適切な時間に更新する方法はありますか?

select() の前にタイマーを手動で開始することを考えましたが、このタイマーはselect()で使用されているものと同期していない可能性があります。また、他の潜在的な問題を引き起こす可能性があります。

4

3 に答える 3

3

selectマニュアルページによると:

Linux では、select()スリープしていない時間を反映するようにタイムアウトを変更します。他のほとんどの実装では、これは行われません。(POSIX.1-2001 では、どちらの動作も許可されています。)

したがって、単にtimeout変数を再利用するだけです。本当にタイムアウトしたときにのみ、その値をリセットします。

警告が示すように、この動作に依存すると移植の問題が発生するため、この動作に依存する場合は、コードを移植するときに正しいことが行われるように文書化してください。

于 2013-04-24T01:04:12.323 に答える
1

time()を呼び出す前に変数を覚えておいて、戻ったときselect()に別のものを取得し、次の反復では を使用せず、タイムアウト値に使用します。time()select()while(1)55 - difference_between_times

おそらく、 を使用してnew_timeout = 5 - difference_between_times % 5、リターン後操作にselect5 秒以上かかる場合でもtimeout、5 秒間隔を設定します。

おそらく秒単位ではなく、より細かい時間単位を使用する必要があります。そして、上記が本当に必要な動作であるかどうかを考えてください(モジュロを使用)。場合difference_between_times > 5によっては、5 秒だけ待つ必要があります。あなたが望むようにしてください、しかしあなたはアイデアを得ます。

于 2013-04-24T00:50:43.367 に答える
1

When your app gets a little more complicated, you may have multiple timers with different timeout intervals. We do. Here is how we handle it.

Each timer has a timer object with a time_t of when the timer expires. We store all the timers in a heap data structure, so the soonest timer to expire is at the root of the heap. Before doing a select() we fetch the root of the heap, and subtract the current time from the timer's expiration time and use that delta as the timeout to the select() call.

Timer * t = heap->Root();
time_t now = time(0);
timeval tv;
tv.tv_sec = t->when - now;
tv.tv_usec = 0;
select( ... & tv );
于 2013-04-24T03:29:45.473 に答える