Std::condition_variable线程争用
std::condition_variable thread contention
我有一个问题,我的condition_variables似乎没有相互通知。从我所读到的看来,condition_variable
不能正常工作的主要原因是锁只在"等待"线程中使用。也就是说,我下面的代码在wait和notify线程中都使用了互斥锁,但仍然不能正常运行。
我错过了什么吗?
谢谢。
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
std::condition_variable cv_one;
std::condition_variable cv_two;
std::mutex m_one;
std::mutex m_two;
void one( )
{
std::unique_lock< std::mutex > lock { m_one };
cv_one.notify_one( );
std::cout << "one" << std::endl;
}
void two( )
{
{
std::unique_lock< std::mutex > lock { m_one };
cv_one.wait( lock );
std::cout << "two" << std::endl;
}
{
std::unique_lock< std::mutex > lock { m_two };
cv_two.notify_one( );
}
}
void three( )
{
std::unique_lock< std::mutex > lock { m_two };
cv_two.wait( lock );
std::cout << "three" << std::endl;
}
int main( int argc, char **argv )
{
std::thread thread_one( one );
std::thread thread_two( two );
std::thread thread_three( three );
std::cin.get( );
cv_one.notify_all( );
thread_three.join( );
thread_two.join( );
thread_one.join( );
return 0;
}
条件变量没有相互通知,因为您在错误的时间进行了通知。例如,如果one
在 two
调用cv_one.wait(lock)
之前调用cv_one.notify()
,那么two
将永远阻塞。就two
所见,在等待时,没有线程通知它。这是@v。Oddou的意思是,通知标志没有被存储。
std::cin
行作为延迟,这就是为什么输出是正确的。在按下按钮所需的延迟时间内,所有线程都到达了它们等待条件变量的位置。
您可以在这个代码示例中看到发生的问题,它显示了线程在被唤醒时开始等待的时间。我切换到单个字符,这样输出就不会乱成一团。
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
std::condition_variable cv_one;
std::condition_variable cv_two;
std::mutex m_one;
std::mutex m_two;
void one()
{
std::unique_lock< std::mutex > lock { m_one };
std::cout << "x" << std::endl;
cv_one.notify_one();
std::cout << "a" << std::endl;
}
void two()
{
{
std::unique_lock< std::mutex > lock { m_one };
std::cout << "y" << std::endl;
cv_one.wait( lock );
std::cout << "b" << std::endl;
}
{
std::unique_lock< std::mutex > lock { m_two };
cv_two.notify_one();
}
}
void three()
{
std::unique_lock< std::mutex > lock { m_two };
std::cout << "z" << std::endl;
cv_two.wait( lock );
std::cout << "c" << std::endl;
}
int main( int argc, char **argv )
{
std::thread thread_one(one);
std::thread thread_two(two);
std::thread thread_three(three);
std::cout << "d" << std::endl;
cv_one.notify_all();
thread_three.join();
thread_two.join();
thread_one.join();
return 0;
}
相关文章:
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 并行块(线程清理器)之外的 OpenMP 中的争用条件;误报?
- C++:用IIFE线程初始化静态局部变量安全吗
- 设计低线程争用的多线程聊天服务器
- 尽管互斥锁,线程中的争用条件
- 线程清理器检测到数据争用,问题出在哪里?
- 什么保证两个不相关的线程中的不同不相关对象没有(不可避免的)争用条件?
- 争用条件 2 个线程交替
- 从多个线程写入内存区域是否会导致争用?
- 如何在同一个线程上用同一个互斥对象锁定两次
- 当只有一个线程写入 c++ 中的布尔变量时,是否存在争用条件
- 使用 C++11 线程强制线程之间的争用
- GCC 的 TSAN 报告了线程安全静态本地的数据争用
- 使用packaged_task和线程可能的数据争用
- 线程安全、无数据争用、无延迟的共享容器 (circular_buffer)
- 在线程争用下等待的最快方法
- Std::condition_variable线程争用
- C++线程争用条件模拟
- c++ 11 (c++线程净化)用原子排序非原子操作(误报?)
- std::映射多线程中奇怪的资源争用