2013-08-27 8 views
5

busy-waitingまたはbusy-sleepingループを使用する以外に、wait()システムコールをタイムアウトで使用する方法はありますか。タイムアウトを設定するバージョンのwait()システムコールがありますか?

fork自身とexec子プロセスが実行可能な親プロセスがあります。その後、子供が終了し、適切な手段で出力を取得し、さらに処理を実行するのを待ちます。プロセスが一定の期間内に終了しない場合、プロセスは実行がタイムアウトしたとみなし、何か他のことをします。残念ながら、このタイムアウト検出は問題の性質を考慮すると必要です。

+2

なぜこのようなことが必要なのか尋ねると、心配ですか? (代替案がある場合) –

+0

[Waitpid相当タイムアウト?](http://stackoverflow.com/questions/282176/waitpid-equivalent-with-timeout) –

答えて

4

タイムアウトが必要な待機コールはありません。

代わりに、SIGCHLDのフラグを設定するシグナルハンドラをインストールし、select()を使用してタイムアウトを実装します。 select()はシグナルによって中断されます。

static volatile int punt; 
static void sig_handler(int sig) 
{ 
    punt = 1; 
} 

... 

struct timeval timeout = {10,0}; 
int rc; 

signal(SIGCHLD, sig_handler); 

fork/exec stuff 
//select will get interrupted by a signal 

rc = select(0, NULL,NULL,NULL, &tv); 
if (rc == 0) { 
// timed out 
} else if (punt) { 
    //child terminated 
} 

より多くのロジックはあなたがLinux上で他のあなたが処理する必要がある信号にもかかわらず、

+0

もしあなたがすでにポーリングループをインストールしているのであれば、シグナルを捕捉するようにsignalfdを設定することもできます。 –

3

waitpidは、WNOHANGオプションと睡眠と一緒に使用できます。

while(waitpid(pid, &status, WNOHANG) == 0) { 
    sleep(1); 
} 

しかし、これはアクティブな睡眠になります。しかし、私はwaitタイプの関数を使用して他の方法を参照してください。

+0

"私はこれを控えめな最後の手段だと考えています。 – Alex

+0

@Alex私は十分に慎重に質問を読んでいないようだ。しかし、私はこの横の方法を見ていません – hek2mgl

3

を持っている場合、あなたはまた、signalfdを使用してこの問題を解決することができる必要とされています。 signalfdは基本的に一連の信号を受け取り、読み取ることができるfdを作成します。あなたが読んだ各ブロックは、発射した信号に対応しています。 signalfdの利点は、あなたがタイムアウトを可能にすべてがselectpoll、またはepoll、とFDを使用することができるということです

(あなたは彼らが実際に送信されないように。は、sigprocmaskと、これらの信号をブロックする必要があります)、およびすべての他のものも待つことができます。

注:対応するstruct signalfd_siginfoが読み取られる前に同じ信号が2回発生すると、1つの表示のみが表示されます。したがって、SIGCHLDという表示が出たときは、-1を返すまで、waitpid(-1, &status, &WNOHANG)を繰り返し指定する必要があります。

FreeBSDでkqueuekeventタイプEVFILT_PROCを使用すると、より直接的に同じ効果を得ることができます。 (SIGCHLDイベントをキックすることもできますが、EVFILT_PROCを使用すると、すべての子プロセスでグローバルにではなくpidでイベントを指定できます)。これはMac OS Xでも有効ですが、試したことはありません。

関連する問題