C++核心准则CP.26:不要分离线程

2020-07-14 16:19:02 浏览数 (2)

CP.26: Don't detach() a thread

CP.26:不要分离线程

Reason(原因)

Often, the need to outlive the scope of its creation is inherent in the threads task, but implementing that idea by detach makes it harder to monitor and communicate with the detached thread. In particular, it is harder (though not impossible) to ensure that the thread completed as expected or lives for as long as expected.

通常,生命周期超过创建它的线程的需求继承自线程任务,但是通过分离(detach)实现这个想法使得监视和与分离的线程进行通信更加困难。在特殊情况下,很难(虽然不是不可能)确保线程可以像期望的那样中止或继续动作。

Example(示例)

代码语言:javascript复制
void heartbeat();

void use()
{
    std::thread t(heartbeat);             // don't join; heartbeat is meant to run forever
    t.detach();
    // ...
}

This is a reasonable use of a thread, for which detach() is commonly used. There are problems, though. How do we monitor the detached thread to see if it is alive? Something might go wrong with the heartbeat, and losing a heartbeat can be very serious in a system for which it is needed. So, we need to communicate with the heartbeat thread (e.g., through a stream of messages or notification events using a condition_variable).

这段代码是线程的合理用法,其中通常会使用detach()。虽然这个做法存在问题。我们如何监视一个分离的线程以便知道它是否处于活动状态?心跳线程可能发生某些问题,对于需要心跳功能的系统来说,丢失心跳是很严重的问题。因此,我们需要和心跳线程通信(例如通过一个信息流或使用condition_variable的通知事件)。

An alternative, and usually superior solution is to control its lifetime by placing it in a scope outside its point of creation (or activation). For example:

另外一个可选的,通常是更高级的做法是将它放到创建它(或者激活它)的作用域之外。例如:

代码语言:javascript复制
void heartbeat();

gsl::joining_thread t(heartbeat);             // heartbeat is meant to run "forever"

This heartbeat will (barring error, hardware problems, etc.) run for as long as the program does.

心跳线程将会和程序运行同样长的时间(除非发生错误,硬件问题等情况)。

Sometimes, we need to separate the point of creation from the point of ownership:

有时,我们需要将生成视点和所有权视点相分离。

代码语言:javascript复制
void heartbeat();

unique_ptr<gsl::joining_thread> tick_tock {nullptr};

void use()
{
    // heartbeat is meant to run as long as tick_tock lives
    tick_tock = make_unique<gsl::joining_thread>(heartbeat);
    // ...
}
Enforcement(实施建议)

Flag detach().

标记分离(detach)操作。

原文链接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#cp26-dont-detach-a-thread

0 人点赞