Execute callback function on main thread from std::thread

11,413

There are a few ways to do this.

First, your main thread could be running a message loop. In which case, you queue up a message with a payload that tells the main thread to run some code (either carry the code to run via a pointer part of the message to the main thread, or put it in some known spot that the main thread checks).

A second approach is to return something like a std::future<std::function<void()>> object, and the main thread checks if the future is ready. When it is ready, it runs the code.

A third approach is to create a concurrent queue that the main thread waits on, and stuff your message (containing code to run) onto that queue.

All of these things require the active cooperation of the main thread. The main thread cannot be preemted and told to run different code without its cooperation.

Which is best depends on features of your program you did not choose to mention in your question. If you are a graphical GUI with a message loop, use the message loop. If you are a streaming processor that paralellizes some work, and you don't need prompt execution, yet eventually will want to block on the parallel work, a future might be best. If you are a message passing channel-type app, a set of queues might be best.

Share:
11,413
Tushar
Author by

Tushar

Updated on June 06, 2022

Comments

  • Tushar
    Tushar almost 2 years

    I have a requirement of executing a callback function on exit of a std::thread and the callback function should be executed on the main thread.

    On thread creation I need to detach the thread and cannot block the main loop execution for thread completion.

    i tried using std::signal but that does not seem to execute callback function on the main thread

    #include <thread>
    #include <csignal>
    #include <iostream>
    
    
    std::thread::id main_thread_id;
    
    void func2()
    {
        for(int i = 0; i < 10000000; i++)
        {
            // do something
        }
    }
    
    void func()
    {
        for(int i = 0; i < 10; i++)
        {
            func2();
        }
        std::raise(SIGUSR1);
    }
    
    void callback(int signal)
    {
        std::cout << "SIGNAL: " << signal << "      THREAD ID:" << 
        std::this_thread::get_id() << std::endl;
        bool b = std::this_thread::get_id() == main_thread_id;
        std::cout << "IS EXECUTED ON MAIN THREAD: " << b << std::endl;
    }
    
    int main()
    {
        main_thread_id = std::this_thread::get_id();
        std::cout << "MAIN THREAD ID: " << std::this_thread::get_id() << std::endl;
        std::signal(SIGUSR1, callback);
        std::thread t1(func);
        t1.detach();
    
        for(int i = 0; i < 20; i++)
        {
            func2();
        }
    
        if(t1.joinable())
            t1.join();
    }
    

    The result I get is that the callback function is not executed on main thread. Please suggest a way in which I can create a worker thread and call a callback function on main thread upon exit of the thread.

    Thanks for the help