为什么 C++ 线程是可移动的而不是可复制的?
Why c++ threads are movable but not copiable?
正如题名所说,为什么C++线程(std::thread
和pthread
)是可移动的而不是可复制的?如果我们让它可复制,会有什么后果?
关于复制,请考虑以下代码段:
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
.
正如题名所说,为什么C++线程(std::thread
和pthread
)是可移动的而不是可复制的?如果我们让它可复制,会有什么后果?
关于复制,请考虑以下代码段:
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
.