Search code examples
c++multithreadingkillterminate

C++ terminate thread


I know that this question has been asked and answered many times and I know that the best way to end a thread is to use flags and exit the thread function when it is requested. This is also what I am doing at the moment, but my problem is that the thread function runs for a very Long time, so sometimes I need to wait for several hours until the thread ends. My thread function looks something like this:

void threadfunction()
{
    while(!exitRequested)
    {
        doSomeWork();
        object1.doSomeWork();
        object2.doSomeWork();
        while(somecondition)
        {
            object3.doSomeWork();
        }
        object4.doSomeWork();
    }
}

This is just an example and in reality the code looks much more complex. But what I wanted to demonstrate is that I call several class methods which can take some hours to complete (per function).

So what I'm doing at the moment is to check if exit was requested between the functions (e.g. between object1.doSomeWork(); and object2.doSomeWork();) but as I said a function call can take up to several hours, so I need to check if exit was requested whithin those functions. In order to do this I need to pass the exitRequested flag to those functions, but in my opinion this doesn't look very nice and there could be a better solution for this.

One solution I could think of is by throwing exceptions, to create something like this:

void threadfunction()
{
    try {
        while(!exitRequested)
        {
            ...
        }
    } catch (const ExitRequestException &e) {}
}

But then the exception needs to be raised somehow. As far as I know I can't raise an exception in a thread from another thread, right?

Do you have any better Solutions? Or do you think I really need to pass the exitRequested flag to all those functions and pollute my code?


Solution

  • After googling around for a while I found (and created) an answer which is perfectly fine for me, although it only works for pthreads. For non pthreads I can immagine using the concept which is described here.

    So what am I doing now: I am sending a signal to the worker thread. This thread handles the custom signal in a signal handler and raises an exception. This exception is cought in the outer part of the thread function. By using this concept I have the advantage that an exception is thrown and the stack is unwound, so I can close all open resources. Here is my complete working example:

    #include <thread>
    #include <signal.h>
    #include <unistd.h>
    #include <iostream>
    
    using namespace std;
    
    //Custom exception which is used to stop the thread
    class StopException {};
    
    void sig_fun(int s)
    {
        if(s == SIGUSR2)throw StopException();
    }
    
    void threadFunction()
    {
        cout<<"Thread started"<<endl;
        try {
            while(true)
            {
                //Work forever...
                sleep(1);
            }
        } catch(const StopException &e) {
            cout<<"Thread interrupted"<<endl;
        }
        cout<<"Thread stopped"<<endl;
    }
    
    int main(int argc, char *args[])
    {
        //Install Signal handler function
        signal(SIGUSR2, sig_fun);
        pthread_t threadObject;
        thread t([&threadObject]()
        {
            //Store pthread_t object to be able to use it later
            threadObject = pthread_self();
            threadFunction();
        });
    
        string temp;
        cout<<"Write something when you want the thread to be killed"<<endl;
        cin>>temp;
    
        //Send Signal to thread
        pthread_kill(threadObject, SIGUSR2);
        t.join();
    }