【发布时间】:2016-07-15 18:46:56
【问题描述】:
我无法理解 Posix 如何允许任何线程在信号量上解锁(发布)。让我们考虑以下示例:
// sem1 and sem2 are a Posix semaphore,
// properly initialized for single process use
// at this point, sem2 is locked, sem1 is unlocked
// x and y are global (non-atomic, non-volatile) integer variables
// thread 1 - is executing right now
rc = sem_wait(&sem1); // succeeded, semaphore is 0 now
x = 42;
y = 142;
sem_post(&sem2);
while (true);
// thread 2. waits for sem2 to be unlocked by thread1
sem_wait(&sem2);
sem_post(&sem1);
// thread 3
sem_wait(&sem1); // wakes up when sem1 is unlocked by thread2
#ifdef __cplusplus
std::cout << "x: " << x << ; y: " << y << "\n";
#else
printf("x: %d; y: %d\n", x, y);
#endif
现在,根据我所读到的所有内容,这段代码 100% 符合逾越节的犹太教规。在线程 3 中,我们保证看到 x 为 42,y 为 142。我们免受任何种族的影响。
但这是我无法理解的。所有这些线程都可能在 3 个不同的内核上执行。如果芯片内部没有强大的内存排序(ARM、PowerPC)或写入不是原子的(x86 用于未对齐的数据),Core2 上的线程 2 如何可能请求 Core1(忙于线程 1)正确释放数据/完成写入/ 等等?据我所知,没有这样的命令!
我在这里缺少什么?
编辑。请注意,建议的重复并不能回答我的问题。它重申了我的说法,但没有解释如何可能达到这种效果。特别是,它没有解释 Core2 如何在 Core1 的缓存中设置内存屏障。
【问题讨论】:
-
我分享你的困惑。对我来说,这似乎是一个潜在的竞争条件。您阅读的哪一部分表明这是安全的?
-
阅读:pubs.opengroup.org/onlinepubs/9699919799/basedefs/…,其中声明 以下函数相对于其他线程同步内存
-
@flatmouse,无处不在? man sem_overview 例如。
-
@SergeyA 你的链接都没有回答我的问题,它只是重申了我所说的。我在问怎么做。我花了大约 30 秒才找到这个问题的副本。不,你没有问如何,你问的是why:这个问题的标题是Why any thread can unlock a semaphore? Why 是因为
sem_wait()和sem_post()根据我链接到的 POSIX 标准同步内存。您还问我在这里缺少什么?您错过了 POSIX 需要与sem_post()和sem_wait()进行内存同步这一事实。
标签: c++ multithreading posix semaphore