C++
std::thread
multithreading
concurrency
programming tips

How to check if a stdthread is still running?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

In modern C++ programming, multithreading is a powerful technique that allows developers to perform concurrent operations. The std::thread class is a part of the C++ Standard Library, introduced in C++11, which facilitates the creation and management of threads. However, a common task when dealing with multithreading is determining whether a specific thread is still running. This article explores how to achieve that using C++'s std::thread and provides technical insights and examples.

Understanding std::thread Lifecycle

When a std::thread object is created, it represents a single thread of execution. The lifecycle of a std::thread can be summarized as follows:

  1. Creation: The thread starts execution with the entry function provided at creation.
  2. Running: The thread runs its task.
  3. Completion: The thread completes when the entry function returns.
  4. Joinable: A thread is joinable if it has started executing and has not been joined or detached.
  5. Detachment or Joining: The thread can be detached, meaning it runs independently, or joined, meaning the current thread waits for it to finish.

Methods to Check if a std::thread is Running

There is no direct method in C++ to check if a std::thread is still running. However, we can use several indirect methods to achieve this.

Checking with std::future

The std::async function paired with std::future can help us determine the state of a task. Here's an example:

cpp
1#include <iostream>
2#include <thread>
3#include <future>
4#include <chrono>
5
6void longTask() {
7    std::this_thread::sleep_for(std::chrono::seconds(2));
8}
9
10int main() {
11    std::future<void> fut = std::async(std::launch::async, longTask);
12
13    while (fut.wait_for(std::chrono::milliseconds(100)) != std::future_status::ready) {
14        std::cout << "Thread is still running...\n";
15    }
16
17    std::cout << "Thread has finished.\n";
18    return 0;
19}

Polling with a Flag

Another approach is to use a flag to indicate the thread's state. A std::atomic variable can provide a thread-safe way to check if the thread is running.

cpp
1#include <iostream>
2#include <thread>
3#include <atomic>
4#include <chrono>
5
6std::atomic<bool> running(true);
7
8void longTask() {
9    std::this_thread::sleep_for(std::chrono::seconds(2));
10    running = false;
11}
12
13int main() {
14    std::thread t(longTask);
15
16    while (running) {
17        std::cout << "Thread is still running...\n";
18        std::this_thread::sleep_for(std::chrono::milliseconds(100));
19    }
20
21    t.join();
22    std::cout << "Thread has finished.\n";
23    return 0;
24}

Using std::thread::joinable

The joinable method checks if a thread is joinable, but it doesn't directly tell if it is still running. However, it can be used to determine if a thread has started and not yet finished.

cpp
1#include <iostream>
2#include <thread>
3
4void longTask() {
5    std::this_thread::sleep_for(std::chrono::seconds(2));
6}
7
8int main() {
9    std::thread t(longTask);
10
11    if (t.joinable()) {
12        std::cout << "Thread is working...\n";
13    }
14
15    t.join();
16    std::cout << "Thread has completed its work.\n";
17    return 0;
18}

Comparison of Methods

Below is a table summarizing the key characteristics of each method to check if a std::thread is still running:

MethodTechniqueThread-SafeUsage
std::future with asyncAsynchronous task executionYesUse for tasks launched with std::async. Good for managing future tasks.
Polling with a FlagAtomic flag checkingYesSimple implementation for tasks with user-defined running states.
std::thread::joinableChecking joinability (indirect)YesUseful for checking before join, but doesn't show running state directly.

Conclusion

Determining if a std::thread is still running requires using indirect methods since C++ does not provide a direct API call for this task. You can use std::future, an atomic flag, or check for joinability depending on your specific needs. Understanding these methods enables you to handle thread lifecycle effectively and write robust multithreaded applications in C++.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.