我在c中使用并发,我有一个proccess池。为了做到这一点,我让每个孩子都在一个While(True)循环中。杀死孩子我使用全局变量和信号处理程序来修改它打破了循环。
问题是,孩子们使用分配的内存,我想释放它。因此,使用来自父母的简单SIGTERM将无法工作。
GLOBAL:
int sigusr1_count = 0;
void SenalTerminacion() {
++sigusr1_count;
}
signal(SIGUSR1, SenalTerminacion);
CHILD:
While (1) {
if (sigusr1_count != 0) {
break;
}
/* some calculations */
}
print("Hola Stack Overflow\n");
/* freeing memory */
exit(0);
父亲:
kill(pidChild, SIGUSR1);
wait(NULL);
如果我注释掉等待代码的行,则会显示消息。但如果我在程序中等待等待挂起。我可以想象,由于我不了解信号和等待的奇怪东西,孩子没有结束。我有n个孩子。 先感谢您!
答案 0 :(得分:2)
sigusr1_count可能由您的子/父进程缓存(在寄存器文件中 - 编译器执行此操作),而不是从内存中读取(或在子代中完全编译为不变)。将其标记为易失性以防止两者:
volatile int sigusr1_count=0;
更好:考虑使用信号量进行进程间信令,而不是忙于while(1)循环。
答案 1 :(得分:0)
您的信号处理函数具有错误的签名。它必须接受int
类型的一个参数,在该参数中它将接收它被调用来处理的信号编号。它不需要使用所提供的值,但它确实需要声明参数。
正如最初发布的那样,您的信号处理函数实现也是错误的。它执行了一个exit(0)
,这本身就没问题,但这会阻止你的子进程在处理信号后进行任何清理,除了退出处理程序函数。特别是,他们永远无法接听print()
电话。
当你试图终止进程的孩子时,我无法准确解释发生了什么,但我最好的猜测是他们没有收到信号,因此当父母试图wait()
时,它无限期地等待孩子退出,这是永远无法做到的。
当调用处理程序时,您的信号处理程序具有错误的签名会导致意外行为。无论如何,整个程序由于使用不兼容的参数调用signal()
函数而表现出未定义的行为。
在任何情况下,如果您只有在注释掉wait()
电话时才会打印一条消息,那么它可能是由父进程生成的。