提升互斥锁、条件scoped_lock,我在这里用错了吗
boost mutex, condition, scoped_lock , am I using them wrong here?
class MyClass
{
public:
void PushMessage(MyMessage m) // Thread 1 calls this
{
boost::mutex::scoped_lock lock(mMutex);
mQueue.push_back(m);
mCondition.notify_one();
}
MyMessage PopMessage()
{
boost::mutex::scoped_lock lock(mMutex);
while(mQueue.empty())
mCondition.wait(lock);
MyMessage message = mQueue.front();
mQueue.pop_front();
return message;
}
void foo() // thread 2 is running this loop, and supposed to get messages
{
for(;;)
{
MyMessage message = PopMessage();
do_something(message);
}
}
private:
std::deque<MyMessage> mQueue;
boost::mutex mMutex;
boost::condition mCondition;
};
当我运行代码时,PushMessage
被调用,foo()
正在等待PopMessage()
,但PopMessage
永远不会返回。
我认为这里do_something
什么并非无关紧要。
我在这里做错了什么?奇怪的是,上面的代码在 mac 下运行良好,但我在 Linux 上遇到了问题。
提升版本是 1.44.0
谢谢
与其让锁定对象的作用域在解锁之前过期,不如尝试在取消阻止等待线程之前手动解锁PushMessage()
中的互斥锁,即
void PushMessage(MyMessage m) // Thread 1 calls this
{
boost::mutex::scoped_lock lock(mMutex);
mQueue.push_back(m);
lock.unlock(); // <== manually unlock
mCondition.notify_one();
}
这样,当线程 2 解封时,线程 1 包含锁,线程 2 正在尝试获取互斥锁的"交叉"时间。 我不明白为什么这会产生问题,但同样,至少当线程 2 仍然包含锁时,您不会让线程 2 尝试调用lock.lock()
。
我认为您需要 2 个互斥对象,一个用于同步不同线程中的方法调用,一个用于条件等待。你把它们混了。
相关文章:
- 努力将整数转换为链表。不知道我在这里做错了什么
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- File.cpp.o:OpenPose 标志 CMakeFiles/.. 的多重定义/main.cpp.o:首先在这里定
- 为什么thread_local变量在这里从未初始化?
- 为什么我必须在这里使用dynamic_cast
- 在这里,当我们比较 if(vc[i]==vc1[i]) 时,它是向量数组. 实际上比较的值是多少,
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- 为什么 C++20 中的 [[可能]] 属性在这里引发警告?
- 我在这里正确传递参数了吗?
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 移动语义在这里如何工作?
- 如何在这里循环运行?
- 为什么枚举变量在这里是右值?
- 我的C++合并排序代码不起作用。我在这里错过了什么?
- 试图美化这个Arduino代码[初学者在这里]
- 复制交换习惯用法-我们可以在这里使用动态强制转换操作吗
- 在这里使用删除运算符是否正确,我很困惑
- 如何使用模板生成整数序列在这里工作
- 为什么sizeof函数在这里不能正常工作