C语言中的线程和线程安全

时间:2015-07-21 19:50:50

标签: c windows multithreading atomic c99

当需要在多个线程进程之间共享一组通用的全局数据时,我通常使用线程令牌来保护共享资源:

enter image description here

编辑 - 2015年7月22日 (合并 atomics 作为可行选项,根据Jens评论)

我的[第一个]问题是 ,在C中,如果我以这样的方式编写我的例程以保证每个线程访问一个,并且只有一个元素阵列:

enter image description here

有没有理由认为异步和同时访问同一不受保护的数组的不同索引(如图所示)会出现问题?

第二个问题: 鉴于可以作为访问的对象 原子实体,即使存在异步中断 C99 - 7.14 Signal handling )也会使用 atomics < / em> 是一种有效的线程保护方法,用于其他不受保护的变量?

enter image description here

编辑 (澄清以解决评论中的问题):
- 此申请的具体内容:
- 目标操作系统:Windows 7/8/10
- 编译器:符合C99(不能使用C11,包括_ Atomic() type specifier
- H / W:Intel i7系列

3 个答案:

答案 0 :(得分:3)

这(看起来像某种C标准) http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf说:

  

注1:两个执行线程可以更新和访问单独的内存   地点没有相互干扰

     

注13:为a引入赋值的编译器转换   可能共享的内存位置,不会被修改   抽象机器通常被这个标准排除在外   赋值可能会覆盖另一个线程的另一个赋值   在抽象机器执行不具备的情况下   遇到了数据竞赛。这包括数据成员的实现   在单独的内存中覆盖相邻成员的赋值   位置。我们通常也会排除原子载荷的重新排序   所讨论的原子可能是别名的情况,因为这可能   违反了“可见序列”规则。

我理解它的方式,这将排除quamrana的担忧,并保证如果没有数据竞争,对单独的内存位置的无保护写入不应导致未定义的行为。

答案 1 :(得分:2)

在C中,它取决于您的平台,即您的编译器,处理器架构和操作系统的组合。

您的编译器可以选择如何使用内部寄存器和CPU的指令使可执行文件似乎执行程序的意图。 C可能对线程一无所知。通常,操作系统的工作就是提供一个线程库。

可能有处理器可能通过读取比一个元素更大的内存块来执行对数组元素的写入,然后只覆盖在内部寄存器中形成一个元素的正确位,然后编写整个补丁背部。单线程程序可以正常工作,但是两个或多个相互中断的线程可能会导致数组混乱。

另一方面,它可能会很好。

如前所述,只读访问总是很好。

此外,谷歌是你的朋友。它找到了这个stackoverflow question

答案 2 :(得分:1)

如果每个线程正在访问一个不同的数组元素,并且只有它被分配的元素&#34;,这不应该是一个问题。上述两种情况基本相同,因为每个数组元素都有自己的地址。