【问题标题】:What happens if two tasks try to access different parts of a struct at the same time (in c)?如果两个任务尝试同时访问结构的不同部分(在 c 中)会发生什么?
【发布时间】:2021-02-24 11:23:00
【问题描述】:

假设我有一个由两个 mystruct_t 类型的结构组成的数组:

    typedef struct {
      uint16_t member1;
      bool member2;
    } mystruct_t;
    mystruct_t my_array[2];

如果两个任务试图同时访问这个数组的不同部分会发生什么?如果一个任务尝试访问 my_array[0] 而另一个任务尝试访问 my_array[1],这会产生竞争条件吗?

如果两个任务试图同时访问结构的不同部分会发生什么?如果一个任务尝试访问 my_array[0].member1 而另一个任务尝试访问 my_array[0].member2,这会产生竞争条件吗?

更新:我使用的是 c99 版本。

【问题讨论】:

  • struct member access 部分其实是一个很好的问题。这在很大程度上取决于特定系统以及编译器如何生成代码。您不能假定它是线程安全的,但在某些系统上可能是这样。不过,访问数组的不同部分是非常安全的。并行化的整个概念都基于该假设。
  • 什么是“任务”?你是说线程吗?哪个C版本?多线程和相应的内存模型仅从 C11 开始标准化。
  • 如果 member1member2 是非原子位域成员,它们之间没有零长度位域,那么同时更新这些位域成员是不安全的,如C 3.14/3.

标签: c c99


【解决方案1】:

竞争条件意味着两个任务(线程)会根据顺序获得不同的行为。这仅在一个或两个任务正在写入(与仅读取相反)到同一位置(C11)时才起作用。每section 3.14 memory location

注意 1 两个执行线程可以更新和访问不同的内存位置,而不会相互干扰。

注 2 [...]

EXAMPLE 声明为的结构

    struct {
            char a;
            int b:5, c:11, :0, d:8;
            struct { int ee:8; } e;
    }

包含四个独立的内存位置:成员 a、位域 d 和 e.ee 各自独立 内存位置,并且可以同时修改而不会相互干扰。位域 b 和 c 一起构成第四个内存位置。位域 b 和 c 不能同时 修改,但例如 b 和 a 可以。

对于读取(以及写入),由于缓存一致性,您仍可能会受到性能影响。

【讨论】:

  • 感谢您的回答!虽然我使用的是 c99,但无法更改版本,但很抱歉没有在我的问题中指定版本。
  • c99 规范没有定义行为。在实践中,它会以相同的方式工作,但是,您需要查阅编译器文档并验证行为以确定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-18
  • 2015-12-02
  • 2020-11-15
相关资源
最近更新 更多