c - 确保读取整个结构

标签 c multithreading gcc consistency

我在两个线程之间有一个共享结构变量:

struct {
  long a;
  long b;
  long c;
} myStruct;
struct myStruct A;

A 的所有 3 个字段都初始化为零。然后第一个线程将更新它们:

A.a = 1;
A.b = 2;
A.c = 3;

第二个线程将从中读取。我要确保的是第二个线程将读取 A 作为一个整体,旧值 {0, 0, 0} 或新值 {1, 2, 3},而不是像 {1, 2, 0 这样的损坏}. 该结构不适合 64 位,所以我不能使用 gcc 的内置原子,我也不想使用互斥锁,所以我想出了 2 个保护标志:

struct {
  long a;
  long b;
  long c;
  volatile int beginCount, endCount;
} A;

然后第一个线程将:

A.beginCount++;
A.a = 1;
A.b = 2;
A.c = 3;
A.endCount++;

第二个将循环直到获得一致的结构:

int begin, end;
myStruct tmp;
do {
  begin = A.beginCount;
  end = A.endCount;
  tmp = A;
} while (!(begin == A.beginCount && end == A.endCount && A.beginCount == A.endCount))
// now tmp will be either {0,0,0} or {1,2,3}

那两个护旗够了吗?如果不是,请指出可能会破坏它的特定线程调度组合。

编辑 1:我不想使用互斥量的原因是第一个线程具有高优先级,它不应该等待任何事情。如果第一个线程想在第二个线程读取时写入,那么第一个线程仍然写入,第二个线程必须重做读取,直到它获得一致的值。我们不能用互斥量来做到这一点,至少我不知道。

编辑 2:关于环境:此代码在多处理器系统上运行,我为每个线程专用了 1 个完整的 cpu 内核。

编辑 3:我知道没有互斥或原子的同步非常棘手。我已经列出了我能想到的所有组合,但找不到任何一个破解密码。所以,请不要只是说它不起作用,如果您指出它何时会损坏,我将不胜感激。

最佳答案

I don't want to use mutex either

在单处理器系统上,如果第一个线程在写入时被抢占,则读取线程将花费其时间片进行不必要的旋转。在这种情况下,您确实需要一个互斥量。

都是 Linux futexes和 Windows 的 CriticalSections在非争用情况下和多处理器系统上不要进行上下文切换,在屈服之前旋转一段时间。

为什么要重新实现完全相同的机制?

关于c - 确保读取整个结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38672790/

相关文章:

java - 创建新线程报错 "constructor test in class test cannot be applied to given types"

c++ - SFINAE 在创建 "is_iterable"特征时出现问题 - 这是 gcc 错误吗?

在 C 中正确比较字符串

c - C语言中的"Wave Algorithm"(基于Lee算法)

c - 运行程序无输出

C# BackgroundWorker 并行调用 DoWorkEventHandler

java - 兰特流的高性能缓冲

c - '^' 除了检查两个数字是否相等之外,C 中使用的运算符是什么?

C++ 从指针构造

c - 在 C 中使用 makefile 变量