c11中的多线程支持

时间:2012-01-16 05:17:15

标签: c multithreading c11

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

  

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

什么是改进的内存排序模型?如何/从c99标准改变了什么?

如果有人深入研究它们并尝试解释所涉及的语义,我将不胜感激。如果有人深入研究它们,我会很感激。

据我了解,C11支持:

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

我希望我没有错过任何东西? 从现在开始,标准库本身提供(将提供)多线程所需的所有功能,将来不需要POSIX和这样的库(用于多线程支持)?

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

3 个答案:

答案 0 :(得分:51)

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

及其中的参考文献。更多信息可以在 的 Open Std Website

现在,问你的问题:

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

显而易见的答案是,它已被更改为考虑多个线程以及它们如何交互。如果答案稍长,请参阅评论中已提及的C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?。为了深入理解,stackoverflow答案可能不是正确的地方(更不用说有几个子问题!)。但幸运的是Hans Boehm maintains a very good page with interesting links for further reading(再次,请记住,C11和C ++ 11内存模型在语义上是相同的)

我希望我什么都没有错过?

与内存模型一起,您的列表似乎涵盖了C11中的并发性添加。对于其他更改,wikipedia has a list;在我的头脑中,我无法想出维基百科列表遗漏的任何内容。

从现在开始标准库本身提供(将提供)多线程所需的所有功能,将来不需要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。关于GCC的当前状态和计划还有一些注释http://gcc.gnu.org/wiki/Atomic(根据该页面,stdatomic.h可用)。对于其他编译器,这里有各种编译器的C ++ 11状态清单http://www.aristeia.com/C++11/C++11FeatureAvailability.htm。从链接中可以检查并发支持的状态,并假设有问题的供应商计划支持C11,那么C11并发支持可能大致处于同一级别。

答案 1 :(得分:7)

关于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()之前退出所有线程的问题终止。

答案 2 :(得分:2)

Janneb已经给出了很多解释。关于你的上一个问题

  

最后,编译器为上述提供了哪些支持   特征?这些时候是否有时间表的参考   支持?

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

对于P99,我写了wrapper macros,将大部分功能映射到已经是C11语法的内容,或接近它(用于模拟_Generic)。

因此,如果你有一个这样的编译器在POSIX系统上,你可以立即开始使用很多(大多数)C11:所有类型mtx_h等的线程,带有_Atomic的原子,类型泛型宏(语法与C11略有不同),_Static_assert和对齐内容。