"data race"(不是真的)在通知条件变量并解锁关联的互斥锁后
"data race" (not really) after notifying condition variable and unlocking associated mutex
我的问题如下所示。线程 II 可能会错过有关std::condition_variable
的通知;线程 III 可以在它之前获取锁定并更改条件。
/*
Thread I Thread II Thread III
_____________________________________________________________
| lock M | wait for notify | wait for M | |
| cond = stateA | | | |
| notify | unblock | | |
| unlock M | wait for M | lock M | |
| | | cond = stateB | |
| | lock M | unblock M | |
| | check if cond == stateA | | |
| | ... | | / t
*
*/
#include <iostream>
#include <condition_variable>
#include <chrono>
#include <thread>
#include <limits>
#include <mutex>
int main()
{
using namespace std::chrono ;
std::mutex mtx ;
std::condition_variable cv ;
enum EState
{
A , B
} state = B ; // mtx
// possible workaround
using count_t = unsigned long long ;
count_t set_A_state_count = 0 ; // mtx
// 18,446,744,073,709,551,615 - number, that may cause missing ;
// ( if Thread III function would get executed exactly this number of times
// before Thread II acquire the mutex )
// believe it is not relevant for present days.
auto ThreadI = [ &set_A_state_count , &cv ,
&mtx , &state ] ()
{
std::lock_guard< std::mutex > lock { mtx } ;
state = A ;
++ set_A_state_count ;
cv.notify_one() ;
} ;
auto ThreadIII = [ &cv , &mtx , &state ] ()
{
std::lock_guard< std::mutex > lock { mtx } ;
state = B ;
} ;
std::unique_lock< std::mutex > lock { mtx } ;
std::thread thI ( ThreadI ) , thIII ( ThreadIII ) ;
const auto saved_count = set_A_state_count ;
if ( state != A ) {
while( saved_count == set_A_state_count ) { // pred ()
// releasing and waiting
cv.wait( lock ) ;
// acquiring - place where ThreadIII can outrun main thread ( ThreadII on the inlustration )
}
}
count_t times = ( saved_count < set_A_state_count ) ?
set_A_state_count - saved_count
: std::numeric_limits< count_t >::max() -
set_A_state_count + saved_count ;
std::cout << "state was changed to A " << times << " times." << std::flush ;
thI.join() ;
thIII.join() ;
return 0;
}
有什么办法可以解决这个问题吗?
(应用程序(。考虑一些带有"wait( state ("、"start"和"cancel"方法的"alarm"类。它有关联的线程,即"服务员"线程。可以在单个对象上调用所有方法。虽然取消和启动可以与其他互斥锁同步,但由于明显的原因,无法等待。可以通过在每次等待之前简单地存储一些 ulong 计数器的状态,然后比较存储和当前 - 如果它们不同(通过启动或取消递增(,则状态切换,发生通知。
线程 II 可能会错过有关
std::condition_variable
的通知;
如果在发出通知时没有线程等待条件变量通知,则可能会错过条件变量通知。代码必须等待状态的更改。条件变量通知是状态可能已更改且必须重新评估的提示。
您有 2 个线程竞相将state
更改为 A
并相应地B
。它们之间没有排序约束,因此state
可以是A
的,也可以是B
的。在后一种情况下,等待state == A
的线程永远阻塞。
相关文章:
- 我应该在锁定TBitmap画布后解锁它吗
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- c++ 为什么我不应该从不同的线程解锁互斥锁
- 在新作用域中使用unique_lock是否等效于在使用共享资源的工作结束时解锁调用
- "data race"(不是真的)在通知条件变量并解锁关联的互斥锁后
- 程序输入密码并解锁窗口7,8,10
- 在通知之前完成手动解锁
- STD :: Mutex如何在不同的线程中解锁
- 如何使用单个解锁方法(可称为读取器或写入器)实现C++读写器锁?
- 如何在C 中自动汇总日志消息并自动解锁互斥X
- 如果我们已经手动解锁了unique_lock,那么破坏时会解锁吗?
- 正在解锁手动未定义/不良设计的锁定guard
- 从C 运行代码后解锁绑定(在R中)的问题
- 在功能返回之前,可以解锁Mutex会增加并发
- 当互斥锁解锁时,它会notify_all或notify_one
- 如何确保在C ++中解锁储物柜?哪种解决方案更好
- 我应该如何在一个功能中锁定wxMutex,并在另一个功能中将其解锁
- mutex::lock() 检查一次解锁状态是否已经被另一个线程锁定?
- 在Qt 5.4中可以对互斥对象进行两次解锁吗
- C++线程:等待condition_variable后无法解锁阵列中的互斥锁