处理SIGTERM后,无法使用条件变量正确退出子进程

如何解决处理SIGTERM后,无法使用条件变量正确退出子进程

我创建了一个子进程,负责处理从父进程发送的SIGTERM。在子进程中,我正在新线程cv内的 condition_variable waitingForWork()上等待。 cvSIGTERM函数中的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;
}

我在下面看到印刷品。

enter image description here

解决方法

[support.signal] / 3 评估是信号安全的,除非它包括以下内容之一:

(3.1)—调用任何标准库函数,但无锁无原子操作和明确标识为信号安全的函数除外。
...

如果信号处理程序调用包含不安全信号的评估,则它具有未定义的行为。

在信号处理程序中几乎没有人可以安全地做。 printf,互斥量和条件变量操作都可以解决。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?