【发布时间】:2021-08-30 04:27:48
【问题描述】:
来自 Anthony Williams 的“C++ Concurrency in Action”。
作者定义了一个thread_guard 类,该类在构造时传递对std::thread 的引用,并在销毁时尝试join() 同一线程。
这是定义
class thread_guard
{
std::thread& t;
public:
explicit thread_guard(std::thread& t_):t(_t){}
~thread_guard()
{
if(t.joinable())
{
t.join();
}
}
thread_guard(thread_guard const&)=delete; // why?
thread_guard operator=(thread_guard const&)=delete; // why?
};
struct func; // function object, definition not included here
void f()
{
int some_local_state = 0;
func my_func(some_local_state); // passing in a local variable
std::thread t(my_func);
// ensure that thread finishes before exiting f()
thread_guard tg(t);
do_something_in_current_thread();
}
我的问题是为什么不允许使用复制构造函数和赋值运算符(使用delete)?
作者说复制会很危险,因为thread_guard 复制“可能会超过它加入的线程的范围”。
但我很困惑——这难道不是一种风险,即使是原始对象(对象将超过线程的范围)?这不就是为什么在析构函数中有一个检查,if t.joinable()?
我在这里错过了什么基本的东西。
【问题讨论】:
-
线程保护副本可以在另一个线程中创建。然后它持有的原始线程被原始thread_guard加入......
-
... 并且 thread_guard 副本在超出范围之前检查原始线程是否是 joinable()... 问题出在哪里?
-
if(t.joinable()) t.join();不是原子的,这就是问题所在。两个线程都可以完成检查,然后尝试加入。
标签: c++ multithreading c++11