正如题名所说,为什么C++线程(
std::thread
和pthread
)是可移动的而不是可复制的?如果我们让它可复制,会有什么后果?
关于复制,请考虑以下片段:
void foo();
std::thread first (foo);
std::thread second = first; // (*)
当标记为
(*)
的行发生时,大概已经执行了一些foo
。那么预期的行为是什么?从一开始就执行foo
?暂停线程,复制寄存器和状态,然后从那里重新运行?
特别是,鉴于 函数对象 现在是标准的一部分,通过重用函数对象,很容易启动另一个线程来执行与某个早期线程完全相同的操作。
因此,没有太多的动力开始。
不过,关于移动,请考虑以下几点:
std::vector<std::thread> threads;
没有移动语义,就会有问题:当向量需要在内部调整大小时,它如何将其元素移动到另一个缓冲区?查看更多信息here.
如果
thread
对象是可复制的,谁最终负责与thread
对象关联的单线程执行?特别是,join()
会为每个 thread
对象做什么?
有几种可能的结果,但这就是问题所在,有几种可能的结果没有真正的重叠,可以编纂(标准化)为一般用例。
因此,最合理的结果是 1 个执行线程最多与 1 个
thread
对象关联。
并不是说不能提供一些共享状态,只是用户需要在这方面采取进一步的行动,比如使用
std::shared_ptr
.