Search code examples
c++multithreadingstdthread

block the main thread to wait for its child threads


So I have this class:

class foo {
public:
        foo() { };
        void me1() const {
            while(1) {
                std::lock_guard<std::mutex> ldock(m);
                std::cout << 0;
            }
        }
        void me2() const {
            while(1) {
                std::lock_guard<std::mutex> ldock(m);
                std::cout << 1;
            }
        }
private:
    std::mutex m;
};

Now I want to run this two methods in some two different threads, I do it like this:

int main() {

    foo myfoo;

    std::thread firstThread(&foo::me1, &myfoo);
    std::thread secondThread(&foo::me2, &myfoo);

    firstThread.detach();
    secondThread.detach();

    //while(1) { }

    return 0;
}

I don't want to wait for any of this two methods to finish, they will simultaneously run until the main thread will be killed.

Is it ok to have some kind of infinite-loop at the end of main thread? (like the commented while(1) {}).

Or should I call some kinda sleep function?


Solution

  • If you want to determine if the two threads have finished your best bet is actually not to detach() the threads but rather join() them before exiting the main thread. That is, you'd kick off both threads and they'll run concurrently and once kicked off you simply join() each. Of course, that assumes that the threads would terminate.

    Having a detach()ed thread effectively means you can never be sure if it has finished. That is generally rarely useful and I consider it a mistake that detach() was added to std::thread. However, even with detach()ed thread you can recognize when an objective is achieved without a busy wait. To that end you'd set up suitable variables indicating completion or progress and have them protected by a std::mutex. The main thread would then wait() on a std::condition_variable which gets notify_once()ed by the respective thread upon the completion/progress update which would be done in reasonable intervals. Once all threads have indicated that they are done or have achieved a suitable objective the main() thread can finish.

    Using a timer alone is generally not a good approach. The signalling between threads is typically preferable and tends to create a more responsive system. You can still used a timed version of wait() (i.e., wait_until() or wait_for()), e.g., to alert upon suspecting a somehow hung or timed-out thread.