4

私のプログラムはシグナルを使用して処理を制御しているため、この関数を使用しselect()て1秒間待機したいので、sleep()途中で戻ります。奇妙なことに、select()それを使用すると、時期尚早に戻ってしまいます。

私はこのようにselectと呼んでいます

struct timeval timeout;    
timeout.tv_sec = 10;  
timeout.tv_usec = 1000000; 
select (0 ,NULL, NULL, NULL, &timeout);

しかし、信号が到着するたびに、それは戻ります(私は信号にナノ秒タイマーを使用しています)

誰もが理由を知っていますか?

4

2 に答える 2

6

次のようなものを試してください。

struct timespec timeout;
timeout.tv_sec = 10;
timeout.tv_nsec = 0;
while (nanosleep(&timeout, &timeout) && errno == EINTR);

「残り時間」ポインタnanosleepは、中断された場合に必要な残り時間でスリープを再開できるようにします。

于 2011-03-04T21:35:24.060 に答える
5

man 7 signal言う:

シグナルハンドラによるシステムコールとライブラリ関数の中断

システムコールまたはライブラリ関数コールがブロックされているときにシグナルハンドラが呼び出された場合は、次のいずれかを実行します。

   * the call is automatically restarted after the signal handler
     returns; or

   * the call fails with the error EINTR.

これらの2つの動作のどちらが発生するかは、インターフェイスと、SA_RESTARTフラグを使用してシグナルハンドラが確立されたかどうかによって異なります(sigaction(2)を参照)。詳細はUNIXシステムによって異なります。以下に、Linuxの詳細を示します。

次のインターフェイスのいずれかへのブロックされたコールがシグナルハンドラによって中断された場合、SA_RESTARTフラグが使用されていれば、シグナルハンドラが戻った後、コールが自動的に再開されます。そうしないと、呼び出しはエラーEINTRで失敗します。

一般に、戻り値が-1でerrno == EINTRであるかどうかを確認してから、関数を再呼び出しすることが、これを修正する正しい方法です。

于 2011-03-04T19:56:34.163 に答える