jeudi 5 novembre 2020

Not able to exit the child process properly using condition variable after handling a SIGTERM

I have created a child process where I am handling a SIGTERM sent from the parent process. In the child process I am waiting on a condition_variable cv inside a new thread waitingForWork(). cv is set by the SIGTERM signal handler inside stopTheWait() function.

For some reason the stopTheWait() function cannot acquire the lock and waitingForWork() waits for ever and doTheCleanUp() is never called.

#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;
}

I see below print.

enter image description here

Aucun commentaire:

Enregistrer un commentaire