C/C++ 和其他语言中的条件变量使用模式
Posted
技术标签:
【中文标题】C/C++ 和其他语言中的条件变量使用模式【英文标题】:Condition variable usage pattern in C/C++ and other languages 【发布时间】:2015-12-08 20:07:20 【问题描述】:如果您查看描述条件变量 (cv) 用法的文档,您会看到例如在 PThreads 和 C++ 中,您无需持有 cv 的互斥锁即可在此 cv 上调用 notify。而例如在 Java 和 Python 中,您必须锁定互斥体才能执行相同的操作。
考虑到像 Java 这样的语言的实现最终会使用一些本机线程工具,是否有一些深层原因为什么会以这种方式实现(我是关于后一种情况)?
【问题讨论】:
可能它不是在 pthreads 之上实现的 .. 但这只是一个假设。我觉得这个问题在cs.stackexchange.com 上可能会得到更好的(甚至任何)答案... 显然 JVM 可以这样实现它,但它犯了一个常见的错误,我见过很多很多人在 c++ 中以相当低的成本做的可能性很小(你需要持有一个锁有点长,但就是这样) @Voo 错误是在修改条件所依赖的数据时没有持有互斥锁? @vehsakul 检查条件(这通常取决于正在修改的数据)而不持有锁。是的,在某些情况下这是完全有效的,但它为错误创造了很大的机会。托管语言归根结底都是关于交易性能的选项以确保安全。我个人认为这里的权衡是合理的,我不认为有很多现实生活中的例子会产生很大的不同。 @Voo 好的,您关于安全与性能的观点很明确。 【参考方案1】:Java notify
和notifyAll
基本同步工具都要求您在调用它们之前对对象进行同步。这是为了一个简单的安全点,因为它还要求您在 wait
ing 之前同步它们。
例如,如果您有两个线程。一个线程从缓冲区读取数据,一个线程将数据写入缓冲区。
读数据线程需要等到写数据线程完成将一个数据块写入缓冲区,然后才能读取该块。
如果 wait()
、notify()
和 notifyAll()
方法可以在不同步的情况下调用,那么您可以获得一个竞争条件:
读取线程调用wait()
,线程被加入等待队列。
同时,写入线程调用notify()
表示已添加数据。
读取线程错过了更改并永远等待,因为notify()
在wait()
之前被处理。
通过强制 wait
和 notify
在同步块内发生,可以消除这种竞争条件。
【讨论】:
以上是关于C/C++ 和其他语言中的条件变量使用模式的主要内容,如果未能解决你的问题,请参考以下文章