- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
是否需要同步std::condition_variable/condition_variable_any::notify_one
?
据我所知,如果丢失通知是可以接受的 - 可以调用未 protected notify_one
(例如通过互斥锁)。
例如,我看到了以下使用模式(抱歉,不记得在哪里):
{
{
lock_guard<mutex> l(m);
// do work
}
c.notify_one();
}
但是,我检查了 libstdc++ 源代码,发现:
condition_variable::notify_one
void condition_variable::notify_one() noexcept
{
int __e = __gthread_cond_signal(&_M_cond);
// XXX not in spec
// EINVAL
if (__e)
__throw_system_error(__e);
}
和condition_variable_any::notify_one :
void condition_variable_any::notify_one() noexcept
{
lock_guard<mutex> __lock(_M_mutex);
_M_cond.notify_one();
}
这里是 condition_variable_any 的布局:
class condition_variable_any
{
condition_variable _M_cond;
mutex _M_mutex;
// data end
即它只是 condition_variable+mutex 的薄包装。
所以,问题:
condition_variable_any
或 condition_variable
不使用互斥体保护 notify_one
是否是线程安全的?condition_variable_any::notify_one
和 condition_variable::notify_one
的实现不同?也许 condition_variable::notify_one
需要手动保护,但 condition_variable_any::notify_one
不需要?是 libstdc++ 错误吗?最佳答案
I.e. it is just thin wrapper around condition_variable+mutex.
呃,不。仅仅因为它具有这些类型的成员并不能使它成为一个薄包装器。尝试了解它实际上做了什么,而不仅仅是它的私有(private)成员的类型。那里有一些非常微妙的代码。
- Is it thread-safe to not protect notify_one by mutex for either condition_variable_any or condition_variable?
是的。
实际上,在互斥锁被锁定的情况下调用notify_one()
会导致等待线程被唤醒,尝试锁定互斥锁,发现它仍然被通知线程锁定,然后重新进入休眠状态直到互斥锁被释放。
如果您在没有锁定互斥锁的情况下调用 notify_one()
,那么唤醒线程可以立即运行。
2 Why implementation of condition_variable_any uses additional mutex?
condition_variable_any
可以与任何 Lockable 类型一起使用,不仅仅是 std:mutex
,而是在 libstdc++ 内部使用 condition_variable
,它只能和std::mutex
一起使用,所以它内部也有一个std::mutex
对象。
所以 condition_variable_any
与两个互斥锁一起工作,一个由用户提供的外部互斥锁和一个由实现使用的内部互斥锁。
3 Why implementation of condition_variable_any::notify_one and condition_variable::notify_one differs? Maybe condition_variable::notify_one requires manual protection but condition_variable_any::notify_one doesn't? Is it libstdc++ bug?
不,这不是错误。
标准要求调用 wait(mx)
必须以原子方式解锁 mx
并休眠。 libstdc++ 使用内部互斥体来提供原子性保证。如果其他线程即将等待 condition_variable_any
,则必须锁定内部互斥体以避免错过通知。
关于c++ - 我是否需要同步 std::condition_variable/condition_variable_any::notify_one,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15887306/
此代码是实际项目代码的简化。主线程创建工作线程并使用 std::condition_variable 等待工作线程真正启动。在下面的代码中,std::condition_variable 在 curr
reference I'm using用以下方式解释这两者: wait_for "阻塞当前线程,直到条件变量被唤醒或在指定的超时时间之后" wait_until "阻塞当前线程,直到条件变量被唤醒或到
标题问题的较长版本是: On my machine, sizeof(std::condition_variable) is 72 bytes.What are these 72 bytes used
假设我有这样的事情: bool signalled = false; std::condition_variable cv; void thread1() { while (true) {
我在下面的代码中遇到错误。 recursive_mutex m_RecurMutex; condition_variable cond; unique_lock lock(m_RecurMutex);
这是什么: bool ready; boost::mutex mutex; boost::condition_variable cond; boost::unique_lock lock(mutex)
这个问题是关于condition_variable.wait()的功能。我认为它可能没有锁定 unique_lock当它被通知时立即。让我展示一下我的代码,您会更好地理解我的测试。 注意:编译器 g+
我是条件变量的新手,我想知道为什么计数器变量等于 99 之后的这段代码块?删除for循环并改用“counter += 99”使代码工作,它与sleep_for有什么关系吗?感谢您的帮助:) #incl
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
似乎 condition_variable notify_one 并不总是按应有的方式工作。 struct Task { std::mutex mutex; std::conditio
条件变量可用于向其他线程发出信号,表明发生了某些事情: mutex m; condition_variable cv; thread t1([&cv]{ // processing .
没有 std::condition_variable 的应用程序: #include #include #include #include #include #include std::m
首先是我的代码,让我的解释更清楚: struct Foo { std::condition_variable cv; }; static Foo* foo; // dynamically cr
std::condition_variable::notify_one() 或 std::condition_variable::notify_all() 是否保证非原子内存写入当前线程之前该调用将在
我目前正在对并发队列进行编程,同时学习如何使用C++ 11的多线程功能。 当使用者调用dequeue()函数且队列中没有任何条目时,该函数应等待,直到另一个线程调用enqueue()为止。我正在为此使
我有一个关于notify_one函数的问题。在下面的代码中, #include #include #include #include #include std::condition_vari
我有一个以下类(class)- boost::condition_varaible cond_; 当我尝试编译时- [rmitra @ butterfly boost] $ make EXE = th
这是一个小代码段 request_ptr pop() { request_ptr rp; std::unique_lock lock(cv_mtx); auto time =
假设我有一个包含std::queue的ThreadQueue类,并且我将每个std::ref的实例传递给线程。进一步假设,线程1(主线程)创建并保存ThreadQueue对象,并将消息倒入其中,第二个
我有课,用 queue的 std::function成员和方法 Push和 Pop . 我要实现加法PushAndWaitUntilExecuted .当你有一个时很容易consumer-thread
我是一名优秀的程序员,十分优秀!