前几天,我问here如何在不使用fork()的情况下使用C启动程序。这个解决方案工作正常.....除了我不能杀死这个子进程! 我的程序(在这种情况下,'rbfeeder')有一些线程....当我发送kill信号时,只有线程被杀死(我认为)。我做错了什么?
这是用于“启动”rbfeeder的代码:
\DB::enableQueryLog();
\DB::getQueryLog();
这是“停止”的代码:
/*
* Start dump1090, if not running
*/
void startDump(void) {
if (p_dump != 0) {
log_level(8, "Looks like dump is already running.\n");
return;
}
pid_t ret = run_cmd("/home/jmaurin/dev/client/rbfeeder");
if (ret != 0) {
log_level(8, "Ok, started! Pid is: %i\n", ret);
p_dump = ret;
sendStats();
} else {
log_level(8, "Error starting dump1090\n");
p_dump = 0;
sendStats();
}
return;
}
和run_cmd函数:
void stopDump(void) {
if (checkDumpRunning()) {
log_level(3, "Dump is running, let's try to kill.\n");
if (kill(p_dump, SIGKILL) == 0) {
log_level(3,"Succesfull kill dump!\n");
sendStats();
return;
} else {
log_level(3,"Error killing dump.\n");
return;
}
} else {
log_level(3, "Dump is not running.\n");
}
return;
}
p_dump是一个保存PID的全局变量。
此图像是我的“客户端”收到命令(通过以太网)启动外部程序时:
然后,在同一台机器上的HTOP ....看到PID是相同的,这意味着我的变量是正确的:
然后,我发送了一个'stop'命令,我的客户端执行'stopDump',但是一个进程仍在运行(来自同一程序的其他线程被'杀死'):
外部程序本身并不“生成/派生”,但它确实有线程。
答案 0 :(得分:3)
你的杀戮成功完成,因为这个过程正在变成一个僵尸,(HTOP中状态栏中的Z)。僵尸是一个仍然在内核中有元数据的进程,但实际上并没有运行。为了摆脱僵尸,父母必须等待这个过程。由于您的进程是父进程,因此在kill成功后添加对waitpid(p_dump)
的调用应处理此问题。
答案 1 :(得分:0)
user1937198的答案运行良好,但我找到了另一种不需要调用任何功能的方式,例如' waitpid'。
struct sigaction sigchld_action = {
.sa_handler = SIG_DFL,
.sa_flags = SA_NOCLDWAIT
};
sigaction(SIGCHLD, &sigchld_action, NULL);
至少在我的情况下,它会在杀死后阻止僵尸进程。它工作正常。