处理 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 cvcvstopTheWait() 函数内的SIGTERM 信号处理程序设置。

由于某种原因,stopTheWait() 函数无法获取 lockwaitingForWork() 永远等待并且永远不会调用 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 后无法使用条件变量正确退出子进程的主要内容,如果未能解决你的问题,请参考以下文章

caffe之路-SIGTERM信号捕捉

无法在 Qt 中退出 exec 循环

终止应用,多个嵌套子流程

如何在LinuxShell中强制python退出

如何在LinuxShell中强制python退出

postgres数据库启动参数