简体   繁体   中英

C++ thread equivalent of pthread_exit

I need a C++ equivalent of pthread_exit in order to make a function that when called cause the calling thread to exit.

In C, using pthreads.h I simply called pthread_exit . I'm new to C++ and need to use its <thread> for which I cannot find a similar function.

I'm using C++17, and the code has to compile on Linux (and possibly on MacOs).

There's no direct way to do this - the normal way to terminate a thread is to return from the top-level function that is called when the thread starts up - but you can achieve the same effect by throwing an exception at the point where you wish to terminate the thread and catching it in the thread's top-level function. This has the advantage that the thread's stack is correctly unwound and any relevant destructors get called.

For example:

#include <iostream>
#include <thread>
#include <exception>

class thread_exit_exception : public std::exception {};

void thread_subfunc ()
{
    std::cout << "Entering thread_subfunc\n";
    thread_exit_exception e;
    throw e;
    std::cout << "Leaving thread_subfunc (never executed)\n";
}

void thread_func ()
{
    std::cout << "Entering thread_func\n";
    try
    {
        thread_subfunc ();
    }
    catch (const thread_exit_exception&)
    {
    }
    std::cout << "Leaving thread_func\n";
}

int main()
{
    std::cout << "Entering main\n";
    std::thread t = std::thread (thread_func);
    t.join ();
    std::cout << "Leaving main\n";
}

Output:

Entering main
Entering thread_func
Entering thread_subfunc
Leaving thread_func
Leaving main

Live demo

C++ is more reliant on its call stack than C is. C++ programs often use RAII, which means that resources are bound to objects that frequently live on the stack. Users of such objects expect those objects to be destroyed properly. If a function creates a stack object, it expects that at some point in the future, control will return to that function and the stack object will be destroyed.

As such, there is no mechanism for a thread with some stack depth to simply go away. A std::thread only ends when the end of the function passed to the thread constructor is reached (an exception emitted from a thread function invokes std::terminate ).

Given this, it is best to restructure your code so that you never need to cause a thread function to exit from some arbitrary place in the call graph. Make it so that the only points where you would want the current thread to exit are places within the thread's main function.

For example, the typical way a thread pool works is that each thread's main function goes to sleep, waiting on some form of task to be dropped off for that thread. When a task is available, it executes that task. Upon the task's completion, it checks for a new task, and if none is available, it goes back to sleep until a task is ready.

In such a thread pool, no thread ever stops . Individual tasks stop, but the actual std::thread is eternal (or at least, lives as long as the pool).

If a task needs to terminate, then such termination essentially represents a failure to perform the task. In C++, that's spelled "throwing an exception". The main thread would put all task invocations in a try block, with a catch block for the specific exception type. It can then report to whomever that a task failed, then go check for a new task.

And this makes sure that the task's call stack is cleaned up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM