共享内存linux变量多进程同步为什么会出错? [重复]

问题描述 投票:0回答:0

我创建一个共享内存,用于在进程之间共享数据。共享内存使用数据结构保存数据:

struct shared_cfg {
    volatile uint32_t idx;
    volatile uint32_t cfg_lock;
    ...
};

在我的程序中:

  • 不同的进程每次都应该得到唯一的“idx”值。
  • 进程P1修改可访问的“idx”后,进程P2期望使用“idx”的新值并更新它。
  • 然后 P1 将获得 P2 保存的新值。
  • ...

但是我发现当并发增加的时候,P2偶尔会读到“idx”的旧值,也就是说P1和P2得到了相同的idx值:

typedef volatile uint32_t lock_t

void lock_idx(lock_t *lock)
{
    uint32_t old_lock = 0;
    do {
        old_lock = __sync_val_compare_and_swap(lock, 0, 1);
        if (old_lock == 1)
            usleep(10*1000);
        else
            break;
    } while (old_lock == 1);
}
void unlock(lock_t *lock)
{
    __sync_lock_test_and_set(lock, 0);
}

idx = 0;

P1:

lock_idx(&cfg_lock);
idx = idx + 1;
unlock_idx(&cfg_lock);

P2

lock_idx(&cfg_lock);
idx = idx + 1;
unlock_idx(&cfg_lock);


修改“idx”前后通过API“mm*fence”插入内存屏障,问题依然存在:

idx = 0;

P1:

lock_idx(&cfg_lock);
_mm_mfence()
idx = idx + 1
_mm_mfence()
unlock_idx(&cfg_lock);

P2:

lock_idx(&cfg_lock);
_mm_mfence()
idx = idx + 1
_mm_mfence()
unlock_idx(&cfg_lock);

错误日志是这样的:

P1: get lock 
P1: idx is 1; update idx to 2 
P1: unlock

P2: get lock 
P2: idx is 2; update idx to 3 
P2: unlock 

... 
P1: get lock 
P1: idx is 63; update idx to 64 
P1: unlock

P2: get lock 
P2: idx is 63; update idx to 64 
P2: unlock 
...

如何通过共享内存在多个进程之间共享变量?

linux synchronization shared-memory memory-barriers thread-synchronization
© www.soinside.com 2019 - 2024. All rights reserved.