Skip to content

Threads

Threads

The C++ thread support library includes built-in support for threads, mutual exclusion, condition variables, and futures.

1
2
3
find_package(Threads)
add_executable(multithreading multithreading.cpp)
target_link_libraries(multithreading PUBLIC Threads::Threads)

1
std::thread t1([]() { std::cout << "function 1\n"; });

1
2
std::thread t2(
    [](int x) { std::cout << "function 2: number " << x << '\n'; }, 10);

1
2
auto fn = [](int x) { std::cout << "function 3: number " << x << '\n'; };
std::thread t3(fn, 2);

1
2
3
t1.join();
t2.join();
t3.join();

1
2
3
4
5
6
// - A vector can store reusable threads
// - The cost of creating threads might be higher than their work
std::vector<std::thread> workers;
for (int i = 0; i < 5; i++) {
    workers.emplace_back([i]() { std::cout << "Thread function " << i; });
}

1
2
std::for_each(workers.begin(), workers.end(),
              [](std::thread &t) { t.join(); });

1
2
3
4
5
6
7
8
// - Unfortunately, async does not necessarily go to a thread pool
// - It's best to use a library if you need async(...) a lot
std::future<int> f2 = async(std::launch::async, [] { return 8; });
while (f2.wait_for(std::chrono::milliseconds(100)) !=
       std::future_status::ready) {
    // do some other work
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
}

1
f2.wait();

1
std::cout << f2.get() << '\n';

1
2
3
// - Same overhead applies here
std::vector<int> v(10000, 1);
std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
template <typename Iter> int parallel_sum(Iter beg, Iter end) {
    typename Iter::difference_type len = end - beg;

    // Solve small problems in one thread
    if (len < 1000) {
        return std::accumulate(beg, end, 0);
    }

    // Split large problems into two threads
    Iter mid = beg + len / 2;
    std::future<int> handle =
        std::async(std::launch::async, parallel_sum<Iter>, mid, end);
    int sum = parallel_sum(beg, mid);
    return sum + handle.get();
}

Share Snippets