2013-01-10 123 views
6

我無法理解以下程序的輸出。我觀察到在子進程返回後,父進程在wait()之前3秒沒有休眠。如果SIGCHLD設置爲默認處理程序,則它會休眠3秒鐘,等待並按預期返回。這裏究竟發生了什麼?當子進程終止時瞭解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在被信號中斷時不會重新啓動。

+0

感謝您的回答。還有一個疑問 - 我從帖子中讀到,重新啓動系統調用取決於其實現定義,並且一些系統調用根本不會重新啓動。是這樣嗎?重新啓動系統調用是否與調用同一個調用兩次相同? – Goutham

+0

@Goutham不一樣。把它想象成「試圖不返回'EINTR'的信號。是的,信號重啓主要取決於實現。 – cnicutar

11

man for sleep()

睡眠()使調用線程休眠直到秒已經過去或信號到達未忽略。

你的孩子終止會導致一個信號喚醒你。

sleep()的返回值:

零,如果要求的時間已經過去,或秒數左側睡,如果呼叫是由信號處理程序中斷。

可以使用,如果你想幫助你「完成」睡眠。

unsigned sleep_time = 3; 
... 
while((sleep_time = sleep(sleep_time)) > 0) {} 
pid = wait(&status); 
... 
相關問題