c++ - 处理 SIGTERM 后无法使用条件变量正确退出子进程
问题描述
我创建了一个子进程,我正在处理SIGTERM
从父进程发送的消息。在子进程中,我在一个新线程中等待一个condition_variable 。由函数内部的信号处理程序设置。cv
waitingForWork()
cv
SIGTERM
stopTheWait()
由于某种原因,该stopTheWait()
函数无法获取lock
并waitingForWork()
永远等待并且doTheCleanUp()
永远不会被调用。
最后父进程关闭。
#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;
}
我看到下面的打印。
解决方案
[support.signal]/3评估是信号安全的,除非它包括以下内容之一:
(3.1) — 对任何标准库函数的调用,除了普通的无锁原子操作和明确标识为信号安全的函数。
...如果信号处理程序调用包含非信号安全的评估,则它具有未定义的行为。
在信号处理程序中几乎没有什么可以安全地做的。printf
,互斥量和条件变量操作一目了然。
推荐阅读
- redux - 同时使用useselector和usedispatch时,会导致无线环路
- excel - 工作表复制动态单元格
- linux - 除了检查 /boot/config_xx 和 /proc/config.gz 之外,如何确认特定 Linux 内核的 preempt rt 选项是否启用?
- flutter - 如何在 Flutter 的 Text 类中显示列表值
- excel - 如何在excel_中获取数据表的公式
- python - np.median error on array of masked array ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()
- kotlin - 使用 IntelliJ IDEA 的 Kotlin “发生了非法反射访问操作”是什么意思?
- npm - 如何卸载浏览器同步
- makefile - 函数“通配符”看不到 $@
- html - 如何将链接定位到右上角区域?(以标题为相对的绝对定位)