2013-01-10 25 views
6

次のプログラムの出力を理解できません。子プロセスが戻った後、親プロセスはwait()の前に3秒間スリープしていないことがわかりました。 SIGCHLDがデフォルトのハンドラに設定されている場合、3秒間スリープ状態になり、waitを呼び出して期待どおりに戻ります。ここで何が起こっているのですか?子プロセスが終了したときのSIGCHLDの理解

# include <unistd.h> 
# include <sys/types.h> 
# include <stdio.h> 
# include <sys/wait.h> 
# include <signal.h> 

void handler(int sig) { 
printf("Iam in handler ...\n"); 
} 

main() { 

int status; 
pid_t pid; 

struct sigaction act; 
//act.sa_flags=SA_NOCLDSTOP; 
act.sa_handler=handler; 
sigaction(SIGCHLD,&act,NULL); 

if(!fork()) { 
printf("child process id is %d\n",getpid()); 
return 1; 
} 

printf("xxx ...\n"); 
sleep(3); 
pid = wait(&status); 
printf("process terminated is %d\n",pid); 

} 

output:: 

xxx ... 
child process id is 2445 
Iam in handler ... 
process terminated is 2445 

答えて

8

子プロセスが終了すると、SIGCHLDが親に送信されます。あなたの場合、それはsleepを中断し、プロセスがスリープしていないかのように見えます。

問題の要点:sleepは、信号によって中断されたときに再開されません。 man for sleep()から

+0

回答ありがとうございます。もう1つの疑問 - 私はシステムコールの再起動が定義された実装までであり、システムコールのいくつかは全く再起動しないという記事から読みました。本当ですか?システムコールの再起動は同じコールを2回呼び出すのと同じですか? – Goutham

+0

@Gouthamそれは同じではありません。それを「EINTRを返さないようにしようとする信号」と考えてください。そうですね、信号の再起動はほとんどが実装依存です。 – cnicutar

11

秒経過したか、信号を無視されていない到着するまで

睡眠は()呼び出しスレッドはスリープになります。

あなたの子が着信すると、目覚め信号が発生します。

sleep()からの戻り値:要求された時間が経過した、またはコールがシグナルハンドラによって中断された場合の秒数は、スリープ状態に放置すれば

ゼロ。

睡眠を「終了」する場合に使用できます。

unsigned sleep_time = 3; 
... 
while((sleep_time = sleep(sleep_time)) > 0) {} 
pid = wait(&status); 
... 
関連する問題