返回介绍

9.4 并发

发布于 2024-08-19 12:44:36 字数 2209 浏览 0 评论 0 收藏 0

尽管做出了英勇的努力,并正在形成广泛的共识,但是人们所期望的通用并发模型(执行器)在 C++20 中还没有准备好(§8.8.1)。这并非是因为缺乏努力,我们的努力中包括了 2018 年 9 月在华盛顿州贝尔维尔举行的为期两天的特别会议,约有 25 人出席,其中有来自英伟达、Facebook 和美国国家实验室的代表。不过,有几个不那么剧烈的有用改进还是及时完成了,其中包括:

  • jthread 和停止令牌 [Josuttis et al. 2019a]
  • atomic<shared_ptr<T>> [Sutter 2017b]
  • 经典的信号量 [Lelbach et al. 2019]
  • 屏障和锁存器 [Lelbach et al. 2019]
  • 小的内存模型的修复和改进 [Meredith and Sutter 2017]

jthreadjoining thread的缩写)是一个遵守 RAII 的线程;也就是说,如果 jthread 超出作用域了,它的析构函数将汇合线程而不是终止程序:

void some_fct()
{
    thread t1;
    jthread t2;
    // ...
}

在作用域的最后,t1 的析构函数会终止程序,除非 t1 的任务已经完成,已经 joindetach,而 t2 的析构函数将会等待其任务完成。

一开始的时候(C++11 之前),很多人(包括我在内)都希望 thread 可以拥有如今 jthread 的行为,但是根植于传统操作系统线程的人坚持认为终止一个程序要远比造成死锁好得多。2012 年和 2013 年,Herb Sutter 曾经提出过汇合线程(joining thread)[Sutter 2012, 2013a]。这引发了一系列讨论,但最终却没有作出任何决定。2016 年,Ville Voutilainen 总结了这些问题,并为将汇合线程纳入 C++17 发起了投票 [Voutilainen 2016a]。投票支持者众多以至于我(只是半开玩笑地)建议我们甚至可以把汇合线程作为一个错误修复提交给 C++14。但是不知何故,进展又再次停滞。到了 2017 年,Nico Josuttis 又一次提出了这个问题。最终,在八次修订和加入了停止令牌之后,这个提案才成功进入了 C++20 [Josuttis et al. 2019a]。

停止令牌解决了一个老问题,即如何在我们对线程的结果不再感兴趣后停止它。基本思想是使用协作式的线程取消方式(§4.1.2)。假如我想要一个 jthread 停止,我就设置它的停止令牌。线程有义务不时地去检查停止令牌是否被设置了,如果被设置了就进行清理和退出。这个技巧由来已久,几乎对于每一个有主循环的线程都能完好高效地工作,在这个主循环里就可以对停止令牌进行检查。

像往常一样,命名成了问题:safe_threadithreadi 代表可中断)、raii_threadjoining_thread,最终成了 jthread。C++ 核心指南支持库 (GSL) 中称其为 gsl::thread。说真的,最合适的名字就是 thread,但是很不幸,那个名字已经被一类不太有用的线程占用了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文