Threads in C++#

#include <thread>

Creating Threads is Far Too Easy#

No parameterization#
void f() { ... }
std::thread t(f);
std::bind?#
void f(int i) { ... }
std::thread t(f, 666);
Lambdas#
std::thread t([](){ ... });

Looks all pretty familiar, no?

Joinable vs. Detached#

Why wait for termination?

  • Wait for a calculation to finish

    • Distribute parallelizable algorithm over multiple CPUs

  • Graceful program termination

Synchronize caller with termination of t#
t.join();

Why detach a thread?

  • Background service thread ⟶ program lifetime

Detach a thread#
t.detach();

Cornercases in Thread Lifetime#

What if the program terminates before a thread?

int main() { std::thread t([](){for(;;);}); }

On Linux, at least …

  • When a process terminates, all its threads terminate immediately

Can I terminate a thread without its cooperation?

  • In Linux, yes, theoretically

  • What happens with locked mutexes?

  • ⟶ Cancellation hooks (hell!)

Portably, no!

Native Handle#

You may need the thread’s OS specific handle (pthread_t on Linux), at times. Be it to tune your threads into a realtime application (see Scheduling And Realtime), or simply to shoot yourself in the foot - read on for two ways.

An ancient way to reliably shoot foot and terminate one’s existence is to use the aptly named kill() system call (see Signals for more).

#include <signal.h>
#include <unistd.h>

int main()
{
    kill(getpid(), SIGSEGV);
    return 0;
}

A multithreaded application has multiple existences. You can use pthread_kill() to specify which foot to shoot. You use the .native_handle() property of std::thread, and pass that into pthread_kill().

#include <thread>
#include <pthread.h>
#include <signal.h>

int main()
{
    std::thread foot([](){for(;;);});
    pthread_kill(foot.native_handle(), SIGSEGV);
    return 0;
}