2013-11-09 92 views
1

我有兩個處理程序(SIGTSTP,SIGCHLD),事情是當我用SIGTSTP暫停一個進程時,SIGCHLD的處理函數也運行了。我該怎麼做才能防止這種情況發生。
SIGTSTP和SIGCHLD之間有什麼關係

信號處理程序:

void signalHandler(int signal) { 
int pid, cstatus; 
if (signal == SIGCHLD) { 
    susp = 0; 
    pid = waitpid(-1, &cstatus, WNOHANG); 
    printf("[[child %d terminated]]\n", pid); 
    DelPID(&JobsList, pid); 
} 
} 

void ctrlZsignal(int signal){ 
    kill(Susp_Bg_Pid, SIGTSTP); 
    susp = 0; 
    printf("\nchild %d suspended\n", Susp_Bg_Pid); 
} 

Susp_Bg_Pid用於保存暫停進程ID。
susp表示如果該進程被暫停或停止,則「粉碎」父進程的狀態。

+0

看來,用正確的標誌,你可以告訴哪個孩子被暫停,以及它收到了哪個信號。所以這不僅可以讓你檢測到實際的退出,還可以採取一些行動來暫停/恢復。 –

回答

2

使用sigactionSA_NOCLDSTOP設置您的SIGCHLD處理程序。

從的sigaction(2)

SA_NOCLDSTOP - 如果signum是SIGCHLD,當子進程停止沒有收到任何通知(即,當他們收到SIGSTOP,SIGTSTP,SIGTTIN或SIGTTOU之一)或恢復(即,他們收到SIGCONT)(請參閱wait(2))。該標誌僅在爲SIGCHLD建立處理程序時纔有意義。

更新

void signalHandler(int sig) 
{ 
    //... 
} 

struct sigaction act; 

act.sa_handler = signalHandler; 
sigemptyset(&act.sa_mask); 
act.sa_flags = SA_NOCLDSTOP; 

if (sigaction(SIGCHLD, &act, 0) == -1) 
{ 
    perror("sigaction"); 
    exit(1); 
} 

如果你不熟悉sigaction你應該讀了它,因爲它是遠遠優於signal但付出的代價幾個不同的選項和行爲在弄清楚如何使用它之前,需要考慮複雜性和混淆性。我儘可能少地猜出了你似乎想做的事情,但你需要儘早而不是晚些時候學習。

+0

你能舉個例子嗎?謝謝 – Rawhi

+0

順便說一下,儘管SA_NOCLDSTOP在* nix平臺上可用,它依賴於實現,可能無法在所有平臺上按預期工作。它適用於Linux。 – Duck

相關問題