Linux C:在从共享内存读取时将主进程与多个其他进程同步
Linux C: Synchronize main process with multiple other processes on read from shared memory
我有一个主进程分配共享内存,然后创建多个进程(每个 运行 同一个程序)。这些进程每 2 秒将状态更新写入共享内存的特定区域(这意味着每个进程都有自己的内存区域,因此写入访问之间不需要同步)。
然后主进程遍历共享内存,将单个状态更新组合成一个完整的状态更新(也是每两秒一次)。
我有两个 30 个进程 运行 有时我得到的完整值与两秒的时间范围不匹配(可能是因为某些进程无法每 2 秒精确地写出它们的数据).
因此,我只想将完整的状态更新写入控制台,以防每个进程都更新了它的值。
如何实现?
在许多可能的方法中,一种方法是使用原子操作来创建全局(读取)锁和 "write" 信号量/计数器。
例如,在共享内存的开头,您可以使用以下结构:
/* supports up to 255 parallel processes. Use uint16_t for more. */
struct { _Atomic uint8_t writing_counter; _Atomic uint8_t lock; } sync_ = {0};
每个更新看起来像这样(伪代码):
_Atomic uint16_t lock = atomic_xchange(&sync_.lock, 1);
if(lock){
goto reschedule; /* reschedule the update attempt */
}
atomic_fetch_add(&sync_.writing_counter, 1); /* increase writing counter */
atomic_xor_fetch(&sync_.lock, 1); /* release lock */
/* update */
/* ... */
atomic_fetch_sub(&sync_.writing_counter, 1); /* decrease writing counter */
master 进程需要设法锁定全局锁并确保没有其他进程写入数据。
_Atomic uint16_t lock = atomic_xchange(&sync_.lock, 1);
if(lock){
goto reschedule; /* reschedule the update attempt */
}
if(atomic_load(&sync_.writing_counter)){
atomic_xor_fetch(&sync_.lock, 1); /* unlock before rescheduling */
goto reschedule; /* reschedule the update attempt */
}
/* collect data (be quick, because this is a critical section) */
/* ... */
atomic_xor_fetch(&sync_.lock, 1); /* release lock */
话又说回来,还有很多其他方法可以做到这一点。这真的取决于你真正需要什么。
我有一个主进程分配共享内存,然后创建多个进程(每个 运行 同一个程序)。这些进程每 2 秒将状态更新写入共享内存的特定区域(这意味着每个进程都有自己的内存区域,因此写入访问之间不需要同步)。
然后主进程遍历共享内存,将单个状态更新组合成一个完整的状态更新(也是每两秒一次)。
我有两个 30 个进程 运行 有时我得到的完整值与两秒的时间范围不匹配(可能是因为某些进程无法每 2 秒精确地写出它们的数据).
因此,我只想将完整的状态更新写入控制台,以防每个进程都更新了它的值。
如何实现?
在许多可能的方法中,一种方法是使用原子操作来创建全局(读取)锁和 "write" 信号量/计数器。
例如,在共享内存的开头,您可以使用以下结构:
/* supports up to 255 parallel processes. Use uint16_t for more. */
struct { _Atomic uint8_t writing_counter; _Atomic uint8_t lock; } sync_ = {0};
每个更新看起来像这样(伪代码):
_Atomic uint16_t lock = atomic_xchange(&sync_.lock, 1);
if(lock){
goto reschedule; /* reschedule the update attempt */
}
atomic_fetch_add(&sync_.writing_counter, 1); /* increase writing counter */
atomic_xor_fetch(&sync_.lock, 1); /* release lock */
/* update */
/* ... */
atomic_fetch_sub(&sync_.writing_counter, 1); /* decrease writing counter */
master 进程需要设法锁定全局锁并确保没有其他进程写入数据。
_Atomic uint16_t lock = atomic_xchange(&sync_.lock, 1);
if(lock){
goto reschedule; /* reschedule the update attempt */
}
if(atomic_load(&sync_.writing_counter)){
atomic_xor_fetch(&sync_.lock, 1); /* unlock before rescheduling */
goto reschedule; /* reschedule the update attempt */
}
/* collect data (be quick, because this is a critical section) */
/* ... */
atomic_xor_fetch(&sync_.lock, 1); /* release lock */
话又说回来,还有很多其他方法可以做到这一点。这真的取决于你真正需要什么。