中断调用函数 popen 的进程
Posted
技术标签:
【中文标题】中断调用函数 popen 的进程【英文标题】:Interrupt a process calling the function popen 【发布时间】:2016-12-29 16:58:37 【问题描述】:我需要实现一个子进程来执行一个文件并发送执行结果,这2个进程将与一个共享内存段进行通信。
我的问题是我想在 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);
如何让子进程可中断?
谢谢
【问题讨论】:
你的代码有没有到达 popen 调用?您也在使用 system 执行命令,因此它会等到该命令完成运行后再继续。 是的,它到达了 popen 调用,我添加系统只是为了测试,但如果尝试执行一个文件,例如 sleep(12);超过 10 秒,进程不会停止执行 如果你用 sleep(12) 替换 popen,你的代码会按预期工作吗? 是的,当我更换它时它可以工作。 【参考方案1】:首先,您需要将子 PID 实际存储到 child_pid 中。它是从 fork 为父进程返回的,因此将您的 fork 调用更改为
child_pid = fork();
if(child_pid == 0)
...
否则,您的 kill 调用将被传递一个随机值。幸运的是,它似乎默认为 0,这意味着 kill 意味着杀死同一进程组中的所有进程,因此您的子进程被杀死。
其次,与其调用 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))
....
这样,您只有一个运行可执行文件的子进程,并且您可以了解它何时以及如何退出。
【讨论】:
我认为你应该接受答案,如果它有效:)以上是关于中断调用函数 popen 的进程的主要内容,如果未能解决你的问题,请参考以下文章
Socket进程处理被中断的系统调用及Accept函数返回EINTR错误处理