Prasha
Prasha

Reputation: 401

How to check if a detached std::thread is still running?

For a detached thread we can't use joinable() and using bool variables seems to be not the correct way. Is there a way to check if the detached thread is still alive and running?

Upvotes: 3

Views: 4548

Answers (2)

Peter Ruderman
Peter Ruderman

Reputation: 12485

There are a few ways to tackle this. If you're set on threads, then you can use a std::future<void> to detect when it has exited:

std::promise<void> promised_thread_exit;

std::future<void> thread_exited = promised_thread_exit.get_future();

std::thread(
  [] (std::promise<void> promised_thread_exit)
  {
    promised_thread_exit.set_value_at_thread_exit();
    DoBackgroundWork();
  },
  std::move(promised_thread_exit));
thread.detach();

// later...
thread_exited.get();

However, this seems like lot of work. A std::thread is quite a low level primitive. If the goal is just to perform some work in the background, then std::async is a better option:

std::future<void> work_complete = std::async(std::launch::async, DoBackgroundWork());

// later...
work_complete.get();

In either case, if you need to check on the work's state without blocking, you can do so by waiting on the future with a timeout of 0:

using namespace std::chrono_literals;

//...

if (work_complete.wait_for(0s) == std::future_status::ready)
{
  // work has finished
}

That being said, checking the state like this is rarely necessary. If it seems to be, then you should consider if there's a simpler alternative.

Upvotes: 5

Siliace
Siliace

Reputation: 652

You can use a std::condition_variable to notify your main thread when the detached one is finished:

#include <iostream>
#include <mutex>
#include <thread>

int main()
{
    std::mutex mutex;
    std::condition_variable cv;

    std::thread t([&]() {
        std::cout << "Wait" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));

        std::unique_lock<std::mutex> lock(mutex);
        std::cout << "Thread end" << std::endl;

        cv.notify_all();
    });

    t.detach();

    std::unique_lock<std::mutex> lock(mutex);
    cv.wait(lock);

    std::cout << "Main end" << std::endl;

    return 0;
}

Upvotes: 0

Related Questions