c11中的多线程支持


68

新的C11标准提供了对多线程的支持。
我的问题有点多样化,但肯定可以回答。
我看过C11 n1570草案。
它说:

支持多个执行线程,包括改进的内存排序模型,原子对象和线程本地存储(<stdatomic.h><threads.h>

什么是改进的内存排序模型?与c99标准相比有何​​变化?

除了有人引用标准之外,如果有人深入研究它们并尝试解释所涉及的语义,我将不胜感激。

据我了解,C11提供以下支持:

  • 线程创建和管理
  • 互斥体
  • 条件变量
  • 线程专用存储和
  • 原子物体

我希望我没有错过任何事情吗?
由于现在标准库本身提供了(将提供)多线程所需的所有功能,因此将来将不需要POSIX和此类库(用于多线程支持)吗?

最后,哪些编译器为上述功能提供支持?是否有关于何时支持时间表的参考?
我记得对于C ++ 11,有一个指向编译器支持和功能的链接,也许是这样的?



20
@bdonlan:问题是关于c11而不是c ++ 11。两者都不同。您提供的链接都是针对c ++ 11而不是c11.duh?
Alok保存

3
我即将投票(“完全重复”),因为您的第一个问题(关于测序模型)已经得到解答。回答包含多个问题的问题很困难,因为某人可能只知道您问题的一部分,因此他们的答案永远不会被接受,因为它不能回答整个问题,并且可能永远不会被接受。请分解您的问题,并删除确切重复的部分(或说明为什么它与我链接的问题不同)。
bdonlan

2
...哦,我现在看到的是关于C11的信息,而不是关于C ++ 11的信息。没关系!我仍然建议您拆分问题-您对1)什么是内存排序模型有疑问。(可能由C ++ 11回答,答案将使用不同的语法相似)2)C11是否提供了这一切?3)是否仍然需要pthreads等?4)C11编译器支持进展如何?
bdonlan

1
@bdonlan:我认为1-3Q在逻辑上是相关的,应该组合在一起,这3个中的任何一个的答案都会涉及到所有3个,也许4可以是一个单独的Q,但是我没有理由为此专门开一个Q 。
Alok保存

Answers:


53

首先,不要注销C ++ 11。新标准的并发工作是在C ++ 11的保护下完成的,然后以兼容的明确目标导入C11。尽管在语法上存在一些差异(例如,由于普通C没有模板或函数重载),但从语义上讲,它们在设计上是相同的。为了证明这一点,可以查看WG14论文。例如:

和其中的参考。可以在Open Std网站上找到更多信息

现在,关于您的问题:

什么是改进的内存排序模型?

显而易见的答案是,已对其进行了更改,以考虑到多个线程及其交互方式。有关稍长的答案,请参阅C ++ 11引入的标准化内存模型。这是什么意思?它将如何影响C ++编程?在评论中已经提到过。为了更深入地了解,stackoverflow答案可能不是正确的位置(更不用说几个子问题了!)。但是幸运的是,汉斯·勃姆(Hans Boehm)保持了一个很好的页面,并提供了有趣的链接以供进一步阅读(同样,请记住,C11和C ++ 11内存模型在语义上是相同的)

我希望我没有错过任何事情吗?

与内存模型一起,您的列表似乎涵盖了C11中的并发添加。对于其他更改,维基百科有一个列表;我无法想出维基百科列表上错过的任何内容。

由于现在标准库本身提供了(将提供)多线程所需的所有功能,因此将来将不需要POSIX和此类库(用于多线程支持)吗?

是的,将需要它们。首先,没有人会重写所有使用各种现有线程API的现有代码。其次,很可能将C(++)11线程库实现为各种本机线程库的包装。哎呀,万一有人需要做一些超出C(++)线程库支持的工作,甚至有一种记录的方法可以检索指向底层本机线程的指针。将C(++)11线程库想像成各种本地线程库周围的可移植,最不常用的分母包装器。

最后,哪些编译器为上述功能提供支持?是否有关于何时支持时间表的参考?我记得对于C ++ 11,有一个指向编译器支持和功能的链接,也许是这样的?

我还没有看到任何详细的列表,与C ++ 11相比,C11似乎没有那么多嗡嗡声。以下是即将发布的GCC 4.7的简短通知:http : //gcc.gnu.org/gcc-4.7/changes.html。对于并发支持,可以在以下位置的C ++ 11状态页面中查看对并发的支持:http : //gcc.gnu.org/projects/cxx0x.html。有关http://gcc.gnu.org/wiki/Atomic的GCC的当前状态和计划的一些说明(根据该页面的stdatomic.h可用)。对于其他编译器,这里有各种编译器的C ++ 11状态列表,网址http://www.aristeia.com/C++11/C++11FeatureAvailability.htm。通过链接,可以检查并发支持的状态,并假设有问题的供应商计划支持C11,则C11并发支持可能处于大致相同的水平。


谢谢!几点评论,我并不完全相信c11中的并发性是从C ++ 11受到启发或引入的。任何可信的引用都将使我对接受它感到坚定。关于将来POSIX和多线程库的需求,用户无需费心确保将其安装到位,因为该标准现在要求实现必须将它们安装到位。因此,即使标准lib api只是对本机lib的包装,实现的责任是提供全部包与以前不同。虽然编译器上的链接不错。
Alok保存

@Als:我添加了一些有关并发工作的C ++传统的链接。第二点,请记住:1)在C11变得足够普遍以至可以假定它可用之前,要花很长时间2)即使如此,线程和原子也是标准的可选部分,请参见例如<code> __STDC_NO_THREADS __ </ code>和<code> __ STDC_NO_ATOMICS __ </ code>宏。话虽这么说,恕我直言,内存模型是向前迈出的一大步,因为它指定了编译器应如何通过多个线程访问内存,这有助于使用pthread的程序以及使用C11线程的程序。
janneb 2012年

@Als:又添加了一个链接(n1349)。另外,对于先前注释中的格式化失败,我们深表歉意。
janneb 2012年

是否存在请求“编译器内存访问”屏障的标准方法,该方法将要求编译器确保在执行通过屏障之前所有未完成的写操作都已发布到基础平台,并且所有读取均会检查屏障后某个时间存在的值?许多平台都有多个可用的编译器,这对于为特定平台编写的程序能够在该平台的所有编译器上可靠运行很有帮助,并且创建编译器内存排序障碍的概念似乎很难理解。
超级猫

从Visual Studio 2017开始,有一个标题称为xthreads.h(您可以在thr包含目录的文件夹下找到)。与几乎相同threads.h。但是我相信这只是为了支持C ++线程实现而创建的。尽管如此,它仍然可以正常工作。
annoying_squid

7

关于 What compilers provide support for the above mentioned features?


Pelles C支持C11 <threads.h>。使用Pelles C编译器示例创建线程:

编辑:消除了线程共享数据的问题以及退出main()所有线程之前终止的问题。


3

Janneb已经给出了很多解释。最后的问题

最后,哪些编译器为上述功能提供支持?是否有关于何时支持时间表的参考?

gcc编译器家族(clang,icc,opencc)支持新标准所要求的大多数语义,只是语法上存在差异。(clang甚至_Generic以最新版本实现。)

对于P99,我编写了包装器宏,该将大多数功能映射到已经是C11语法或接近C11语法的东西(用于仿真_Generic)。

因此,如果您具有这些编译器之一并且在POSIX系统上,则可以立即开始使用很多(大部分)C11:具有所有类型的线程mtx_h等,具有的原子_Atomic,类型泛型宏(语法与C11略有不同) ,_Static_assert并且对准东西。


1
“ threads.h”将成为C库(例如glibc)的一部分,而不仅仅是编译器。当前没有C语言库和编译器完全支持“真正的”多线程(从02 / 2k12开始的现在和不久的将来)。
Tomas Pruzina 2012年

@AoeAoe,P99还包含了POSIX线程,包括顶部的“threads.h”部分的完整仿真mtx_tcond_t和类似的东西。
詹斯·古斯特

2
什么定义“海湾合作委员会家庭”?我不知道GNU C编译器,Intel C编译器和Clang之间的关系。
bames53 2012年

6
@ bames53,这些编译器似乎试图在很大程度上与gcc兼容,这是一种简单的关系。特别是它们都将__GNUC__宏定义为某个值。
詹斯·古斯特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.