用信号停止While(True)

时间:2015-03-09 20:43:10

标签: c signals wait

我在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个孩子。 先感谢您!

2 个答案:

答案 0 :(得分:2)

sigusr1_count可能由您的子/父进程缓存(在寄存器文件中 - 编译器执行此操作),而不是从内存中读取(或在子代中完全编译为不变)。将其标记为易失性以防止两者:

volatile int sigusr1_count=0;

更好:考虑使用信号量进行进程间信令,而不是忙于while(1)循环。

答案 1 :(得分:0)

您的信号处理函数具有错误的签名。它必须接受int类型的一个参数,在该参数中它将接收它被调用来处理的信号编号。它不需要使用所提供的值,但它确实需要声明参数。

正如最初发布的那样,您的信号处理函数实现也是错误的。它执行了一个exit(0),这本身就没问题,但这会阻止你的子进程在处理信号后进行任何清理,除了退出处理程序函数。特别是,他们永远无法接听print()电话。

当你试图终止进程的孩子时,我无法准确解释发生了什么,但我最好的猜测是他们没有收到信号,因此当父母试图wait()时,它无限期地等待孩子退出,这是永远无法做到的。

当调用处理程序时,您的信号处理程序具有错误的签名会导致意外行为。无论如何,整个程序由于使用不兼容的参数调用signal()函数而表现出未定义的行为。

在任何情况下,如果您只有在注释掉wait()电话时才会打印一条消息,那么它可能是由父进程生成的。