来自 c++11 29.3-p3:
所有 memory_order_seq_cst 操作上应有一个总顺序 S,与所有受影响位置的“发生在”顺序和修改顺序一致,以便从原子对象 M 加载值的每个 memory_order_seq_cst 操作 B 观察以下任一情况价值观:
-- S 中 B 之前的 M 的最后一次修改 A 的结果(如果存在),或者
-- 如果 A 存在,则在相对于 B 的可见副作用序列中对 M 进行某些修改的结果,该修改不是 memory_order_seq_cst 并且不会在 A 之前发生,或者
-- 如果 A 不存在,则在相对于 B 的可见副作用序列中对 M 进行某些修改的结果,该序列不是 memory_order_seq_cst。
[ 注意:虽然没有明确要求 S 包含锁,但它始终可以扩展到包含锁定和解锁操作的顺序,因为这些操作之间的顺序已经包含在“发生在”顺序中。--注释结束]
最后一个注释中,“总是”是什么意思?我可以理解任何特定的实现都可以设计为支持这样的扩展 S。但是在一些不是为此设计的通用实现中,我看不到 S 可以使用所描述的属性进行扩展。
这是否意味着这里也满足相同可见性属性的扩展订单?
我已将这个问题发送到 comp.std.c++ 但在那里没有得到答案。http://groups.google.com/group/comp.std.c++/browse_frm/thread/5242fa70d0594d1b#
编辑:这不是任何允许在 post() 中互斥锁定的问题的重复。请仔细阅读,我需要一个无锁帖子()!如果您没有真正的答案,请不要标记此重复项。
信号量(如在 Linux 中)是一个有用的构建块,但在 C++ 标准中没有找到,在 boost(目前)中也没有。我主要讨论的是抢占式调度程序中单个进程的线程之间的信号量。
我对它们的非阻塞(即无锁)特别感兴趣,除非它实际上需要阻塞。也就是说,post() 和 try_wait() 应该始终是无锁的。如果 wait() 调用强烈发生在足够的 post() 返回之后,那么 wait() 调用应该是无锁的。此外,阻塞 wait() 应该被调度程序阻塞而不是自旋锁定。如果我还想要一个带有超时的 wait_for 该怎么办 - 它会使实现进一步复杂化,同时仍然避免饥饿?
信号量不在标准中是否有原因?
Edit3:所以,我不知道有一个针对标准 P0514R4 的提案可以准确处理这些问题,并且除了专门添加 std::semaphore 之外,还可以解决此处提出的所有问题。http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0514r4.pdf
而且boost没有这些。具体来说,进程间的进程是自旋锁定的。
哪些库支持类似的东西?
是否可以通过 windows api 和其他广泛的系统来实现它?
编辑:不可能使用原子+互斥体+条件变量来实现无锁 - 您要么必须在发布中阻塞,要么在等待中旋转。如果您想要无锁的 post(),则不能在 post() 中锁定互斥体。我想在可能抢占式的调度程序上运行,并且我不希望 post() 被其他获取互斥锁并被抢占的线程阻塞。那么,这不是像C++0x has no semaphores 这样的问题的重复吗?如何同步线程?
edit2:下面的示例实现只是为了演示使用atomics+mutex+condvar可以完成的最佳操作,据我所知。post() 和 wait() 执行一次无锁比较交换,并且只有在必须时,它们才会锁定互斥锁。
然而 post() 不是无锁的。更糟糕的是,它可能会被锁定互斥锁并被抢占的 wait() 阻塞。
为了简单起见,我只实现了 post_one() 和 wait_one_for(Duration),而不是 post(int) 和 wait_for(int,Duration)。另外,我假设标准没有承诺无虚假唤醒。
class semaphore //provides acquire release memory ordering for the …Run Code Online (Sandbox Code Playgroud)