alx*_*cyl 10 c++ multithreading c++11 stdthread
假设我有一个工作线程tWorker,它在Boss构造时被初始化并告诉它要做work(),直到bRetired为真.An std::mutex,mtx锁定一些data(vFiles),以便tWorker在他处理它时拥有它.
怎样使tWorker"自杀"一度bRetired成为true?mutex当线程停止执行时如何销毁?
我已经读过,std::thread对象不能以任何方式中断.让线程什么也不做(或调用std::this_thread::yield())提供与杀死线程相同的效果?
class Boss {
private:
std::thread tWorker;
std::mutex mtx;
bool bRetired;
std::vector< std::string > vFiles;
void work() {
while ( bRetired == false ) {
// Do your job!
mtx.lock();
// ... Do something about vFiles ...
mtx.unlock();
}
// tWorker has retired, commit suicide
// ** How? **
// Does this suffice if I want to "kill" the thread?
std::this_thread::yield();
}
public:
Boss() {
bRetired = false;
tWorker = std::thread( &Boss::work, this );
// Have worker do its job independently
// **Bonus Question** : Should this be tWorker.join() or tWorker.detach()?
tWorker.detach();
}
retire() {
bRetired = true;
}
}
Run Code Online (Sandbox Code Playgroud)
笔记
一旦bRetired成为现实,我如何让tWorker"自杀"?
您让控制流退出线程功能.那叫std::this_thread::yield()不必要.
当线程停止执行时,如何销毁互斥锁?
该互斥体是Boss类的成员.Boss当对象被破坏时,它会在析构函数中被破坏.
我已经读过std :: thread对象不能以任何方式中断.
C++ API不提供终止任意线程的方法.必须有一种方法告诉线程终止,然后等到它确实如你所愿.
让线程什么都不做(或调用std :: this_thread :: yield())提供与杀死线程相同的效果吗?
没有.
bRetired虽然变量存在竞争条件.它需要std::atomic<bool>或者只有在锁定互斥锁时才能读取和修改它.
调用std::thread::yield()是不需要的并且不会杀死调用线程:
提供实现的提示,以重新安排线程的执行,允许其他线程运行.
只需退出该函数即可退出该线程.
请注意,使用bRetired不正确,因为两个线程可以访问相同的内存位置,其中一个线程正在修改它:这是未定义的行为.此外,retire()执行的线程将不会看到函数中所做的更改(不同的线程)run():atomic<bool>用于原子性和可见性.
如果join()在构造函数中使用,构造函数将不会返回,直到线程退出,这将永远不会发生,因为它无法调用,retire()因为该对象不可用(因为构造函数不会返回).如果需要与线程的退出同步的话就不要detach(),但join()在retire()功能:
void retire() {
bRetired = true;
tWorker.join();
}
Run Code Online (Sandbox Code Playgroud)
使用RAII获取mutexes(std::lock_guard例如)以确保它始终被释放.在mutex当它超出范围,在这种情况下,当其包含的类被破坏就会被破坏.