C 用信号停止一会儿(正确)

C 用信号停止一会儿(正确),c,signals,wait,C,Signals,Wait,我在c中使用并发,我有一个进程池。为了做到这一点,我让每个孩子都在一个While(True)循环中。为了杀死孩子们,我使用了一个全局变量和一个信号处理程序来修改它,打破了循环 问题是,孩子们使用分配的内存,我想释放它。因此,使用来自父项的简单SIGTERM是行不通的 全球: int sigusr1_count = 0; void SenalTerminacion() { ++sigusr1_count; } signal(SIGUSR1, SenalTerminacion); 儿童

我在c中使用并发,我有一个进程池。为了做到这一点,我让每个孩子都在一个While(True)循环中。为了杀死孩子们,我使用了一个全局变量和一个信号处理程序来修改它,打破了循环

问题是,孩子们使用分配的内存,我想释放它。因此,使用来自父项的简单SIGTERM是行不通的

全球:

int sigusr1_count = 0;

void SenalTerminacion() {
    ++sigusr1_count;
}

signal(SIGUSR1, SenalTerminacion);
儿童:

While (1) {
    if (sigusr1_count != 0) {
        break;
    }
    /* some calculations */
}
print("Hola Stack Overflow\n");
/* freeing memory */ 
exit(0);
父亲:

kill(pidChild, SIGUSR1);
wait(NULL);
如果我用wait注释掉该行,则代码将工作,并显示消息。但如果我离开,等待程序挂起。我可以想象,孩子不会因为我不知道的信号和等待而结束。我有四个孩子。
提前谢谢你

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

正如最初发布的,您的信号处理函数实现也是错误的。它执行了一个
退出(0)
,这本身是正常的,但这会阻止您的子进程在处理信号后执行任何清理,退出处理程序函数除外。特别是,他们永远无法访问
print()
调用

我无法确切解释当您尝试终止进程的子进程时会发生什么,但我的最佳猜测是它们没有接收到信号,因此当父进程尝试
wait()
时,它会无限期地挂起,等待子进程退出,这是永远不会发生的

在调用处理程序时,信号处理程序具有错误签名可能会导致意外行为。在任何情况下,由于使用不兼容的参数调用
signal()
函数,整个程序都会显示未定义的行为,这是事实


在任何情况下,如果您仅在注释掉
wait()
调用时才打印消息,那么它可能是由父进程生成的。

sigusr1\u计数可能是由您的子进程/父进程缓存的(在寄存器文件中——编译器这样做了),而不是从内存中读取的(或在子级中完全编译为不变量)。将其标记为volatile以防止:

volatile int sigusr1_count=0;

更好:考虑使用信号量来处理进程间的信令,而不是忙(1)循环。

是否需要使用信号?您可以使用其他IPC,例如管道或UNIX域套接字。“分配内存”是什么意思?只是<代码> MALROCK()/<代码>和<代码> For()?如果是这样,您可以只使用
SIGTERM
,因为当操作系统清理进程时,所有内存将自动释放。我正在这样做,valgrind正在识别内存泄漏。我在信号中有一个打印,其中的代码正在被删除。您是否尝试使用信号量而不是繁忙的lo在进程之间发送信号op?如果你想要一个繁忙的循环,试试atomics,否则我很难预测编译器会如何处理你对全局循环的引用。