2016-12-29 3 views
0

Мне нужно реализовать дочерний процесс, который будет выполнять файл и отправить результат выполнения, процесс 2 будет связываться с сегментом разделяемой памяти.Прерывать процесс, вызывающий функцию popen

Моя проблема в том, что я хочу убить дочерний процесс, вызвав popen через 10 секунд, но функция 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

Имеет ли ваш код когда-либо доступ к коду? Вы также выполняете команду с помощью системы, поэтому она будет ждать, пока она не закончится, прежде чем продолжить. –

+0

Да, он достигает вызова popen, я добавил систему только для теста, но если попытаюсь выполнить файл, который имеет пример для сна (12); более 10 секунд, процесс не прекращает выполнение –

+0

, и если вы замените popen на сон (12), ваш код работает должным образом? –

ответ

1

Во-первых, вам нужно на самом деле сохранить ребенка PID в child_pid. Он вернулся из вилки для родительского процесса, так изменив вилочный вызов

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

иначе ваш звонок, чтобы убить это передается случайное значение. К счастью, кажется, что он по умолчанию равен 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

Я думаю, вы должны принять ответ, если он работает :) –

Смежные вопросы