【发布时间】:2017-06-15 22:15:28
【问题描述】:
我正在尝试解决 C++11 中的生产者消费者问题。 我有一个保存资源的对象,多个线程可以 添加或消耗这些资源。我的问题是当我尝试实施 该对象上的“可用时使用”方法。 请假设插入/删除操作非常复杂。
代码中逻辑的一点解释。
struct ResourceManager{
std::mutex mux;
std::unique_lock lock{mux};
std::condition_variable bell;
void addResource(/*some Resource*/){
lock.lock();
//add resource
lock.unlock();
bell.notify_one(); //notifies waiting consumer threads to consume
}
T getResource(){
while(true){
lock.lock();
if(/*resource is available*/){
//remove resource from the object
lock.unlock();
return resource;
}else{
//new unique lock mutex object wmux creation
lock.unlock(); //problem line
bell.wait(wmux); //waits until addResource rings the bell
continue;
}
}
}
};
假设以下场景:
- 两个线程,T1,T2,几乎同时调用addResource,getResource。
-T2 锁定互斥体,发现没有更多可用资源,
所以它必须阻塞,直到有新资源可用。
所以它解锁互斥锁并设置铃声等待。
-T1 运行匹配更快。当互斥锁解锁时,
它立即添加资源,并在 T2 设置等待铃之前,
T1已经按门铃了,没有人通知。
-T2 无限期等待铃声响起,但不会添加更多资源。
我假设锁定互斥锁的线程可能是唯一的 解锁它。因此,如果我在解锁互斥锁之前尝试调用 bell.wait, 互斥锁永远无法解锁。
如果可能,我想使用不等待时间或多次检查的解决方案。
那么在 C++11 中我可以通过哪种方式解决这个问题呢?
【问题讨论】:
-
可能与您的问题无关,但请使用
std::unique_lock之类的锁守卫来锁定/解锁互斥锁。 -
锁是唯一锁
-
什么是
wmux?您应该锁定lock,并执行bell.wait(lock),以避免出现竞争条件。 -
@FrustratedSoul 哦,对不起。但这不是如何使用它。通常你没有一个成员变量,而是一个局部变量,当它离开它的范围时,它只是解锁互斥锁。
-
@FrustratedSoul:我已经删除了我的解决方案,并邀请您在en.cppreference.com/w/cpp/thread/condition_variable/wait 上检查 unique_lock 和 condition_variable 的正确用法,该示例几乎正是您想要做的。
标签: c++ multithreading c++11 mutex