[英]std::thread when is thread executed?
我已经浏览了一些线程教程,但我很好奇一件事。
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
线程是在我调用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(); }
};
我正在考虑一个合适的位置可能在线程函数的末尾,因为不再需要Child但是如果你试图从内部破坏线程会发生什么? 我猜这听起来不是一个坏主意。 我怎么知道什么时候可以删除我的线程? 有更好的方法吗?
修改上面的代码以反映下面的建议。
我现在意识到教程正在讨论关于抛出异常的内容,所以我应该使用互斥锁而不是mtx.lock()我想。
的目的join
是,本质上,等待线程完成。 所以一旦Child->join();
返回,你的线程已经完成。 当然,您也可以在析构函数中执行Child->join()
[或者在某些其他方面,确保在某些时候调用它]。
请注意,线程将在实际创建的时间和连接结束之间的某个时刻开始运行。 无法确定何时会发生这种情况。 如果系统上已经运行了很多线程,则时间将在所有线程之间分配,并且您的线程可能无法运行几秒钟。 另一方面,如果有一个CPU坐在那里“弄乱它的手指”,它很可能在主线程超出new std::thread(...)
构造之前启动[因为std::thread
won' t返回,直到线程被正确创建,并且一些数据存储在线程对象中,因此在到达Child->join()
时线程可能已经完成。 如果不知道系统处于什么状态,就无法确定这些选项中的哪一个。
操作系统很重要,但它相当普遍。 线程被安排执行。 当操作系统到处实际运行时,完全无法预测。 你可以在拥有多个内核的机器上“快速”获得不错的赔率,这在今天是普遍可用的。
thread :: join()只是确保线程完成执行。 你永远不会真正编写这样的代码,启动一个线程然后等待它完成是完全没有意义的。 也可以直接执行线程的代码。 通过创建线程而不会影响操作系统的结果相同。
您无法知道您的线程将以何种顺序或核心运行。
一个posix线程基本上被linux视为一个与另一个共享其堆的进程。 内核将安排它们并决定使用哪个核心。 例如,查看生成的(受保护的)程序集,您将看不到任何“多核/多线程编程”,因为这是在内核级别完成的。
这就是为什么存在诸如连接之类的函数和诸如互斥锁/信号量之类的工件的原因。 照顾比赛条件和其他相关的东西。
线程是在我调用join()时执行还是在创建线程和调用join之间的某个时间运行?
在创建线程后执行(启动)线程,具体取决于可能需要一些时间的可用资源。 join()
方法等待(阻塞),直到线程完成其工作。
一个建议:我不会将变量命名为Sync
对象This
,令人困惑,因为存在this
关键字。
您可以在Async::Inc()
调用join()
之后安全地删除std::thread
对象,而且您不需要将引用存储为成员变量,它只在该函数中使用。
您还可以查看<atomic>
标头, std::atomic<int>
或std::atomic_int
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.