在 POSIX 中,为什么单个 condvar 不能与多个互斥体一起使用?

In POSIX, why can't a single condvar be used with multiple mutexes?

当 POSIX 条件变量与多个互斥锁一起使用时,为什么行为未定义?

摘自 2018 年版:

When a thread waits on a condition variable, having specified a particular mutex to either the pthread_cond_timedwait() or the pthread_cond_wait() operation, a dynamic binding is formed between that mutex and condition variable that remains in effect as long as at least one thread is blocked on the condition variable. During this time, the effect of an attempt by any thread to wait on that condition variable using a different mutex is undefined

我想是因为某些特定系统的某种实现细节,所以有人可以证实或反驳它吗?

C11(和C17)条件变量似乎没有这样的限制,为什么?

它更像是一个“目的”的东西,std::mutex更像是一个线程向多个线程发送信号,不像std::atomic适用于大多数情况。 undefined 部分可能试图说“it may deadlock itself ”,无论如何它都可能发生,但不是因为图书馆。一些 can't 应该被视为 shouldn't,只是测试 ti 是否适合你,仅此而已(大部分)。

C11 (and C17) condition variables don't seem to have such limitation,

我同意 C11 和 C17 似乎没有记录对 cnd_waitcnd_timedwait 使用的互斥量的任何限制。但是,它们确实允许这些函数失败,并且它们可能失败的一个合理原因是指定了与当前等待指定的相同 CV 的另一个线程不同的互斥锁。

and why?

我只能推测标准委员会的动机和思考过程。可能成员希望允许没有此类限制的实现,并且他们假设其他实现会简单地行使他们的选择权以在需要时失败。可能这只是一个疏忽。

期望多个线程不会同时等待具有不同互斥量的 CV,这对于条件变量实现来说很普通,也适用于条件变量使用模式。 POSIX 的限制绝不是唯一的:

  • C++ std::condition_variable 有一个类似于 POSIX 的
  • 的限制
  • Java 对象的监视器和 java.util.concurrent.locks.Condition 的实现本质上与特定的锁相关联,因此人们甚至不能表达尝试同时使用不同的锁。
  • Python threading.Condition 对象也与特定的锁相关联。

这个答案合乎逻辑,“论证”了我的困惑。感谢 John Bollinger 的启发。

从逻辑上讲,一个互斥体,一个条件变量对象,和一个抽象谓词是关联在一起的,这样一个对condvar returns的等待操作,谓词改变了与手术前相比。特别地,互斥体和谓词之间的关联尤为重要。这与学术界对条件变量的定义一致。

逻辑: 假设有 2 个线程在等待具有 2 个不同互斥量的 condvar,逻辑上这意味着有 2 个 independent 谓词,因此,2 个互斥量 属于 不同的 条件变量 .

实现: 通常,条件变量的实现是在内核支持的信号量上运行的用户 space 子例程,它们在合并时被简化并变得更加线程安全以上逻辑假设。

现实: 这意味着,使用单个 condvar 发出 2 个谓词变化的信号通常比使用 2 个不同的 condvar 发出信号要低得多且更容易出错条件变量