Che*_*tpp 3 c++ multithreading
我已经浏览了一些线程教程,但我很好奇一件事.
std::thread Child([](){ std::cout << "When am I executed?" << std::endl << std::endl; });
//Some other code
Child.join();
//I'm guessing now my thread would be running
Run Code Online (Sandbox Code Playgroud)
线程是在我调用时执行join()还是在创建线程和调用join之间的某个时间运行?如果在join()调用时执行它,只是为了检查我的理解,它告诉执行的部分,你的程序继续在主线程上,最终子线程在主线程正在使用的相同内存上做了一些工作?
如果我想为泛型类创建一个包装器,我会想做类似下面的事情,但我似乎无法完全弄明白.我对在内存方面管理线程很困惑.
class Sync {
private:
int val;
public:
Sync() : val(0) {}
void Inc() {val++}
int Value() { return val; }
};
class Async {
private:
Sync Foo;
std::mutex mtx;
std::vector<std::thread*> Children;
public:
//I would need a new thread each time I called Inc
void Inc() {
Children.push_back(new std::thread([&]() {
mtx.lock();
Foo.Inc();
mtx.unlock();
}));
}
//But how do I know when it is safe to delete Child?
int Value() {
for(auto& thds : Children) {
thds->join();
delete thds;
}
Children.clear();
return Foo.Value(); }
};
Run Code Online (Sandbox Code Playgroud)
我正在考虑一个合适的位置可能在线程函数的末尾,因为不再需要Child但是如果你试图从内部破坏线程会发生什么?我猜这听起来不是一个坏主意.我怎么知道什么时候可以删除我的线程?有更好的方法吗?
修改上面的代码以反映下面的建议.
我现在意识到教程正在讨论关于抛出异常的内容,所以我应该使用互斥锁而不是mtx.lock()我想.
目的join是基本上等待线程完成.所以一旦Child->join();返回,你的线程就完成了.当然,您也可以Child->join()在析构函数中执行[或者在某些其他方面,确保在某些时候调用它].
请注意,线程将在实际创建的时间和连接结束之间的某个时刻开始运行.无法确定何时会发生这种情况.如果系统上已经运行了很多线程,则时间将在所有线程之间分配,并且您的线程可能无法运行几秒钟.另一方面,如果有一个CPU坐在那里"弄乱它的手指",它可能很可能在主线程离开new std::thread(...) 构造之前启动[因为std::thread在线程被正确创建之前不会返回,并且一些数据是存储在线程对象中,因此线程很可能在您到达时完成Child->join().如果不知道系统处于什么状态,就无法确定这些选项中的哪一个.
操作系统很重要,但它相当通用。线程被安排执行。操作系统何时真正开始运行是完全不可预测的。在当今普遍可用的多核机器上,您将有很大的机会“快速”运行。
thread::join() 只是确保线程完成执行。你永远不会真正编写这样的代码,启动一个线程然后等待它完成是完全没有意义的。不妨直接执行线程的代码。相同的结果,不会因创建线程而使操作系统陷入困境。