处理 SIGTERM 后无法使用条件变量正确退出子进程
Posted
技术标签:
【中文标题】处理 SIGTERM 后无法使用条件变量正确退出子进程【英文标题】:Not able to exit the child process properly using condition variable after handling a SIGTERM 【发布时间】:2020-11-05 13:55:31 【问题描述】:我创建了一个子进程,我正在处理从父进程发送的SIGTERM
。在子进程中,我在新线程waitingForWork()
中等待condition_variable cv
。 cv
由stopTheWait()
函数内的SIGTERM
信号处理程序设置。
由于某种原因,stopTheWait()
函数无法获取 lock
和 waitingForWork()
永远等待并且永远不会调用 doTheCleanUp()
。
Parent 进程终于关闭了。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
void stopTheWait()
printf("[CHILD] Stopping the wait.. \n\n");
std::lock_guard<std::mutex> lck(mtx);
cv.notify_all();
void signal_callback_handler(int signum)
printf("[CHILD] Caught signal, trying to stop the wait... %d\n\n",signum);
stopTheWait();
void doTheCleanUp()/* is never called*/
printf("[CHILD] clean up... \n\n");
void waitingForWork()
printf("[CHILD] wait for ever... \n\n");
std::unique_lock<std::mutex> lck(mtx);
cv.wait(lck);
doTheCleanUp();
printf("[CHILD] clean Up Done, now end wait... \n\n");
exit(0);
int main()
printf("[PARENT] in parent...\n");
int pid;
if ((pid = fork()) < 0)
perror("fork");
exit(1);
if (pid == 0)
/* child */
signal(SIGTERM, signal_callback_handler);
std::unique_lock<std::mutex> lck(mtx);
std::thread t1(waitingForWork);
t1.join();
waitingForWork();
printf("[CHILD] wait is over...\n\n");
else /* parent */
/* pid hold id of child */
sleep(3); /* pause for 3 secs */
printf("[PARENT] sending SIGTERM\n\n");
kill(pid, SIGTERM);
sleep(3);
printf("[PARENT] exiting parent...\n");
sleep(1);
return 0;
我看到下面的打印。
【问题讨论】:
【参考方案1】:[support.signal]/3评估是信号安全的,除非它包括以下之一:
(3.1) — 对任何标准库函数的调用,除了普通的无锁原子操作和明确标识为信号安全的函数。 ...
如果信号处理程序调用包含非信号安全的评估,则它具有未定义的行为。
在信号处理程序中几乎没有什么可以安全地做的。 printf
,互斥量和条件变量操作都出来了。
【讨论】:
以上是关于处理 SIGTERM 后无法使用条件变量正确退出子进程的主要内容,如果未能解决你的问题,请参考以下文章