C++14 (又名C++1y)中提出了一些新的线程同步原语:闩锁和屏障。建议是
这听起来是个好主意,而且这些示例使它看起来非常适合程序员。不幸的是,我认为示例代码会调用未定义的行为。这个建议提到了latch::~latch()
毁了门闩。如果当其他线程处于
wait()中或正在调用count_down()时锁锁被销毁,则行为将未定义。
注意,它写的是"in wait()“,而不是”wait()中的阻塞“,这是对count_down()的描述使用的。
然后提供以下示例:
第二个用例的示例如下所示。我们需要加载数据,然后使用多个线程进行处理。加载数据是I/O绑定,而启动线程和创建数据结构则是CPU绑定。通过并行运行这些操作,可以提高吞吐量。void DoWork() {闩锁start_latch(1);vector工作者;for (int i= 0;i< NTHREADS;++i) {workers.push_back(新线程(&{ //初始化数据结构)。这是CPU绑定。..。start_latch.wait();//执行工作.});} //加载输入数据。这是I/O限制。. //线程现在可以开始处理start_latch.count_down();}
在线程从wait()中唤醒和返回,以及当锁存离开作用域时,不是存在竞争条件吗?除此之外,所有的thread对象都是泄漏的。如果调度程序在count_down返回之前没有运行所有的工作线程,并且start_latch对象离开作用域,那么我认为会产生未定义的行为。据推测,修复方法是迭代向量以及join()和delete,所有工作线程都在count_down之后,但在返回之前。
注意:似乎有可能一个或多个工作线程尚未开始等待,因此将在已销毁的闩锁上调用wait()。
更新:现在有一个新版本的提案,但有代表性的例子不变。
发布于 2013-05-15 19:45:51
谢谢你指出这个。是的,我认为示例代码(为其辩护,其目的是简洁)被破坏了。它可能应该等待线程完成。
任何允许线程在wait()中被阻塞的实现几乎肯定会涉及某种条件变量,并且在线程尚未退出wait()时销毁闩锁可能是未定义的。
我不知道是否有时间更新这份报纸,但我可以确保下一个版本是固定的。
阿拉斯代尔
https://stackoverflow.com/questions/16241463
复制相似问题