70

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

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

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

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

据我了解,C11 支持:

  • 线程创建和管理
  • 互斥体
  • 条件变量
  • 线程特定存储 &
  • 原子对象

我希望我没有错过什么?
由于现在标准库本身提供(将提供)多线程所需的所有功能,将来是否不需要 POSIX 和此类库(用于多线程支持)?

最后,哪些编译器支持上述特性?是否有任何关于何时支持这些时间表的参考资料?
我记得对于 C++11,有一个编译器支持和特性的链接,也许是这样的?

4

3 回答 3

55

首先,不要注销 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 并发支持很可能处于大致相同的水平。

于 2012-01-16T08:54:55.193 回答
8

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


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

#include <stdio.h>
#include <threads.h>

#define NUM_THREADS 7

static int threadData[NUM_THREADS];

int threadFunction(void * data) {
    printf("%d-th thread up\n", *(int*)data);
    return 0;
}

int main(void) {
    thrd_t threadId[NUM_THREADS];

    // init thread data
    for (int i=0; i < NUM_THREADS; ++i)
        threadData[i] = i;

    // start NUM_THREADS amount of threads
    for (int i=0; i < NUM_THREADS; ++i) {
        if (thrd_create(threadId+i, threadFunction, threadData+i) != thrd_success) {
            printf("%d-th thread create error\n", i);
            return 0;
        }
    }

    // wait until all threads terminates
    for (int i=0; i < NUM_THREADS; ++i)
        thrd_join(threadId[i], NULL);

    return 0;
}

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

于 2012-05-02T12:30:37.557 回答
3

Janneb已经给出了很多解释。对于您的最后一个问题

最后,哪些编译器支持上述特性?是否有任何关于何时支持这些时间表的参考资料?

gcc 系列编译器(clang、icc、opencc)支持新标准要求的大部分语义,只有语法差异。(clang 甚至_Generic在最新版本中实现。)

对于P99,我编写了封装宏,将大多数特性映射到已经是 C11 语法的东西,或者接近它(用于模拟_Generic)。

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

于 2012-01-25T20:14:16.063 回答