2016-12-29 72 views
0

我需要實現一個子進程,它將執行一個文件併發送執行結果,2進程將與一個共享內存段進行通信。中斷調用函數的進程popen

我的問題是,我想殺死10秒後調用popen的子進程,但函數popen忽略信號。

這裏是我的代碼(不包括共享內存段):

void kill_child(int sig) 
{ 
kill(child_pid,SIGKILL); 
printf("processus killed \n"); 

} 

/*code....*/ 

signal(SIGALRM,(void (*)(int))kill_child); 

if(fork()==0){ 
       res.buffer=true; 
       FILE * fd; 
       char cmd[BUFFER_SIZE],output[BUFFER_SIZE]; 
       strcpy(cmd,"./"); 
       strcat(cmd,res.filepath); 
       system(cmd); 
       if((fd=popen(cmd,"r"))== NULL) 
        exit(1); 
       else 
        res.status=200; 


       strcpy(output,""); 
       while(fgets(buf,sizeof(buf)-1,fd)) 
        strcat(output,buf); 

       if(pclose(fd)) 
        exit(1); 

       strcat(res.customHTML,output); 
       res.buffer=true; 


       int err = sendResponse(res,args->client_fd); 
       if (err < 0) on_error("failed!\r\n"); 



       exit(0); 


} 

else{ 

       int status; 
       alarm(10); 
       waitpid(-1,&status,0); 
       printf("status %d _n); 
} 

怎樣才能使孩子的過程中斷?

謝謝

+0

你的代碼是否曾經到過popen調用?您也正在使用系統執行命令,因此它會在繼續之前等待,直到完成運行。 –

+0

是的,它達到了popen調用,我添加了系統只是爲了測試,但如果試圖執行一個文件,例如睡眠(12);超過10秒,過程不會停止執行 –

+0

,如果您用睡眠(12)替換popen,您的代碼是否按預期工作? –

回答

1

首先,您需要實際將子PID存儲到child_pid中。它從父進程返回,因此將您的分叉呼叫更改爲

child_pid = fork(); 
if(child_pid == 0) 
    { 
... 

否則您的調用kill將被傳遞一個隨機值。幸運的是,它似乎默認爲0,殺死意味着殺死同一進程組中的所有進程,這樣子進程就會被殺死。

其次,而不是調用POPEN()調用與(例如)execvp(可執行你自己),並有家長閱讀使用您自己創建一個管道輸出...

int fds[2]; 

pipe(fds); 
child_pid = fork(); 
if(child_pid == 0) 
    { 
    char *cmd[]={"mycmd",NULL}; 

    /* Replace stdout with the output of the pipe and close the original */ 
    dup2(fds[1],1); 
    close(fds[0]); 
    close(fds[1]); 
    execvp(cmd[0],cmd); 
    } 
else 
    { 
    close(fds[1]); 
    alarm(10); 
    while(...) 
    { 
    read(fds[0],....); 
    if(waitpid(child_pid,&status,WNOHANG)) 
     { 
     .... 
     } 
    } 
    } 

這樣你只有運行你的可執行文件的一個子進程,並且你已經知道它何時以及如何退出。

+0

非常感謝你,這種方式。 –

+0

我認爲你的意思是接受答案,如果它的工作:) –