2012-03-22 81 views
0

我這段代碼執行正確的狀態:wait4和waitpid函數沒有返回

void update_process(PROCSP * process){ 

    int state; 
    printf("process.pid = %d\n", process->pid); 
    if (process->state== TERM || process->state == SIG) 
     return; 
    process->prio = getpriority(PRIO_PROCESS, process->pid); 
    errno = 0; 
    if (wait4(process->pid, &state, WNOHANG | WUNTRACED, &(process->r)) != -1){ 
     if (WIFEXITED(state)) 
      process->state= TERM; 
     else if(WIFSIGNALED(state)) 
      process->state= SIG; 
     else if(WIFSTOPPED(state)) 
      process->state= STOP; 
     else process->state= ACT; 
    } else{ 
     perror("wait4"); 
    return; 
    } 
} 

奇怪的是,當我調用該函數後,打印狀態的價值wait4它不會改變,所以函數給了我錯誤的狀態。 我確定這個過程存在,並且它有正確的pid(至少當我在Linux中執行「ps all」時,它顯示的是與傳遞給函數的pid相同的pid)。

所有這些代碼是叉子和execv(包含在功能CMD_execute)後執行:

void CMD_background(char * argv[]){ 
    if(argv[0]==NULL){ 
     return; 
    } 
    pid_t pid = fork(); 
    if (pid == 0){ 
     CMD_execute(argv); 
     return; 
    } else { 
     background_add_proc(argv, pid); 
    } 
} 

我也改變了wait4到waitpid函數,但同樣的事情發生。

可能是什麼問題?

謝謝!

回答

1

我的手冊頁說When the WNOHANG option is specified and no processes wish to report status, wait4() returns a process id of 0.這可能是發生了什麼事。

state僅在進程實際已退出/停止時設置,並且wait4返回的值大於0.沒有具體說明,但只有這樣纔有意義,因爲沒有WIFRUNNING宏。

+0

就是這樣。謝謝! :) – Ankoku 2012-03-23 10:53:17

1

您可能會忽略SIGCHLD。在這種情況下,您無法檢查子進程的退出代碼。如果看起來你的代碼看起來沒有忽略信號,那麼查看你正在使用的任何第3方庫,我相信Oracle會忽略它,所以一些第三方庫改變了信號的默認行爲。