问题遇到的现象和发生背景
unique_lock 的对象会以独占所有权(没有其他的 unique_lock 对象同时拥有某个 mutex 对象的所有权)
的方式管理 mutex 对象上的上锁和解锁的操作。
这是c++11书上说的一段话,锁是独占,但是在运行代码时,发现,锁竟然被不同的线程,同时获取了,这个就非常纳闷了。希望有懂的朋友,给点指导。
用代码块功能插入代码,请勿粘贴截图
std::mutex mtx;
std::queue<int> product_nums;
std::condition_variable cv;
bool notify_signed = false;
system("chcp 65001");
auto productor = [&]() {
for (int i = 1; ; i++) {
// 睡眠 900 ms
std::this_thread::sleep_for(std::chrono::milliseconds(800));
std::unique_lock<std::mutex> lock(mtx);
std::cout << "------lock---p--- " << std::this_thread::get_id() << std::endl;
std::cout << "产出 : " << i << "|产出id:" << std::this_thread::get_id() << std::endl;
product_nums.push(i);
notify_signed = true;
cv.notify_one();
}
};
auto consumer = [&]() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
std::cout << "------lock---c--- " << std::this_thread::get_id() << std::endl;
while (!notify_signed) { // 避免虚假唤醒
cv.wait(lock);
}
// 短暂取消锁,使得生产者有机会在消费者消费前 生产信息
lock.unlock();
std::cout << "------unlock---c--- " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 消费者要慢于生产者
lock.lock();
// 消费 1 个就推出,避免多次消费
if (!product_nums.empty()) {
std::cout << "消费: " << product_nums.front() << "|消费id:" << std::this_thread::get_id() << std::endl;
product_nums.pop();
}
notify_signed = false;
}
};
运行结果及报错内容
我是用了一个生产线程,两个消费线程运行。
上面是代码,产出下面的结果。有点不太历届,理论上独占锁在占用锁时,其他的锁将不能获取,只能等待,但是这里为什么,都在同时获取lock。
我的解答思路和尝试过的方法
查过一些资料,也没有相关的描述。
我想要达到的结果
希望有懂的朋友,给点指导。