2014-06-21 48 views
8

给定foo_t[n]类型的数组和n线程,其中每个线程读取和修改数组的不同元素,是否需要显式同步数组的修改,或者我可以假设同时修改数组的成员是明确定义的行为?它有多大foo_t是/它有什么路线?定义好的行为是修改数组中的一个元素,而另一个线程修改同一数组的另一个元素吗?

+2

数组的两个不同元素是两个不同的对象,因此有两个不同的内存位置。对不同存储器位置的并行/非同步访问保证是安全的。 (C11)Pre-C11,我认为这不安全。在C11之前,C主要是线程不可知的。 – dyp

+1

@dyp如果foo_t小于字的大小,并且机器只能进行字大小的内存访问,该怎么办?一个成员的修改是否可能也会写出相邻成员的一部分? – fuz

+0

@FUZxxl:在这种情况下,foo_t可能会被填充为字的大小。 –

回答

5

我试图做的是明确的行为。

见ISO/IEC 9899:2011§5.1.2.4.27:

注意的是引进分配到将不被抽象机被修改潜在共享存储器位置13个 编译器变换通常排除按照这个标准,因为在抽象机器执行不会遇到数据竞争的情况下,这样的分配可能会由不同的线程覆盖另一个分配。这包括数据成员分配的实现,用于覆盖单独内存位置中的相邻成员。我们通常也会排除在原子问题可能会混淆的情况下原子加载的重新排序,因为这可能会违反“可见序列”规则。

请注意,此语言是C11引入的优化,导致错误like this非法。 Pre-C11编译器可能不遵守此规则。

+0

我不知道如何严格编译器实际坚持这一点。是否有任何编译器在单线程程序中执行字大小的写入来更新字符串中的字符,但在多线程系统中更改为字节大小的写入? –

+0

@MattMcNabb我真的不知道。 – fuz

+0

该笔记基于C11的线程。所以POSIX的线程实现可能不会遵循相同的规则。 –

相关问题