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 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 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。
查过一些资料,也没有相关的描述。
希望有懂的朋友,给点指导。
查到原因了。是因为std::condition_variable cv;cv.wait 的原因。
执行wait,wait_for 或 wait_until。该操作能够原子性的释放互斥量mutex上的锁,并阻塞这个线程。