繁体   English   中英

C++ 线程等效于 pthread_exit

[英]C++ thread equivalent of pthread_exit

我需要一个等效于pthread_exit的 C++ 来制作一个 function ,当调用它时会导致调用线程退出。

在 C 中,使用pthreads.h我简单地调用了pthread_exit 我是 C++ 的新手,需要使用它的<thread> ,我找不到类似的 function。

我正在使用 C++17,代码必须在 Linux 上编译(可能在 MacOs 上)。

没有直接的方法可以做到这一点 - 终止线程的正常方法是从线程启动时调用的顶级 function 返回 - 但您可以通过在您希望的点抛出异常来实现相同的效果终止线程并在线程的顶级 function 中捕获它。 这样做的好处是线程的堆栈被正确展开并且任何相关的析构函数都被调用。

例如:

#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

现场演示

C++ 比 C 更依赖其调用堆栈。 C++ 程序经常使用 RAII,这意味着资源绑定到经常存在于堆栈上的对象。 此类对象的用户期望这些对象被正确销毁。 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.

因此,没有机制让具有一定堆栈深度的线程简单地离开 go。 std::thread仅在到达传递给thread构造函数的 function 的末尾时结束(从线程 function 调用std::terminate发出的异常)。

鉴于此,最好重新构建您的代码,以便您永远不需要导致线程 function 从调用图中的某个任意位置退出。 使您希望当前线程退出的唯一点是线程的主 function 内的位置。

例如,线程池的典型工作方式是每个线程的主 function 进入睡眠状态,等待某种形式的任务被该线程丢弃。 当任务可用时,它会执行该任务。 任务完成后,它会检查是否有新任务,如果没有可用的,它会重新进入睡眠状态,直到任务准备好。

在这样的线程池中,没有线程会停止 单个任务停止,但实际的std::thread是永恒的(或者至少与池一样长)。

如果一个任务需要终止,那么这种终止本质上就代表了该任务的执行失败。 在 C++ 中,拼写为“抛出异常”。 主线程会将所有任务调用放在一个try块中,并带有一个用于特定异常类型的catch块。 然后它可以向任何人报告任务失败,然后 go 检查新任务。

这可以确保清理任务的调用堆栈。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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