当只有 inc/decrementing 个变量时是否需要互斥锁?

Is a mutex necessary when only inc/decrementing a variable?

我有一个带有一些整数字段的结构,比如

struct s {
    int a;
    int b;
    int c;
    int max;
};
struct s mystruct = {0, 0, 0, 0}; // Global var

然后我有 N 个线程,有时必须在前三个字段上做 ++-- 之类的事情,有时必须读取它们然后更新 max场地。我必须在这里使用互斥锁吗?如果是,是仅在 reading/updating max 时还是始终需要?为什么?如果我只是递增或递减前三个字段,一个线程在另一个线程之前运行是否重要?

并发的通用规则是:如果以非原子方式并发访问内存位置,并且并非所有访问都是读取,则必须对访问进行排序。可以通过锁定互斥锁来序列化访问,或者通过一些较低级别的操作(如有序原子访问或有序栅栏)来强制执行排序。

如果所有 的访问都是读取,那么您唯一一次被允许无序 访问。例如。多个线程可以读取一个(非原子)常量而无需排序。

如果您执行的操作不是原子操作,则需要同步对变量的访问。 考虑一个初始值为 5 的单个变量 a 的场景。 现在我们有两个线程 T1 和 T2,都想增加它。如何分解增量操作,以防它不是原子的(只是一个例子,可能是其他方式)?

1) 将 a 值读入临时位置。
2) 递增并将临时位置写回 a

现在考虑这样一个场景,T1先执行这个操作,然后T2在完成第1步后抢占:

T1: 1) 将 a 读入 temp1 => temp1=5
T2: 1) 将 a 读入 temp2 => temp2=5
T2: 2) 将 temp2+1 写入 a => a=6
T1: 2) 将 temp1+1 写入 a => a=6

因此 a 的最终值将是 6 而不是您期望的 7