为什么 C++ 线程是可移动的而不是可复制的?

Why c++ threads are movable but not copiable?

正如题名所说,为什么C++线程(std::threadpthread)是可移动的而不是可复制的?如果我们让它可复制,会有什么后果?

关于复制,请考虑以下代码段:

void foo();

std::thread first (foo);     
std::thread second = first; // (*)

当标记为 (*) 的行发生时,可能已经执行了一些 foo 。那么预期的行为是什么?从头开始执行foo?暂停线程,复制寄存器和状态,然后从那里重新运行?

特别是,考虑到 function objects 现在是标准的一部分,通过重新使用函数对象,可以很容易地启动另一个线程,该线程执行与某个早期线程完全相同的操作。

因此,没有太多动力开始这样做。


不过,关于移动,请考虑以下几点:

std::vector<std::thread> threads;

没有移动语义,就会有问题:当向量需要在内部调整大小时,它如何将其元素移动到另一个缓冲区?查看更多关于这个 here.

如果 thread 个对象是可复制的,那么谁最终负责与 thread 个对象关联的单线程执行?特别是,join() 会为每个 thread 对象做什么?

有几种可能的结果,但这就是问题所在,有几种可能的结果没有真正的重叠,可以编纂(标准化)为一般用例。

因此,最合理的结果是 1 个执行线程最多与 1 个 thread 对象关联。

并不是说某些共享状态不能提供,只是用户需要在这方面采取进一步的行动,比如使用std::shared_ptr.