代码同时从两个不同的线程获取相同的互斥锁。 我知道应该发生僵局。为什么不发生?
#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
template <typename T>
class SafeQueue
{
public:
T pop()
{
std::unique_lock<std::mutex> mlock(mutex_);
std::cout << "lock pop()" << std::endl;
while (queue_.empty())
{
cond_.wait(mlock);
std::cout << "lock pop awake. Items: " << queue_.size() << std::endl;
}
auto item = queue_.front();
queue_.pop();
std::cout << "returning from pop" << std::endl;
return item;
}
void push(const T& item)
{
std::unique_lock<std::mutex> mlock(mutex_);
std::cout << "lock push()" << std::endl;
queue_.push(item);
mlock.unlock();
cond_.notify_one();
}
private:
std::queue<T> queue_;
mutable std::mutex mutex_;
std::condition_variable cond_;
};
SafeQueue<int> queue;
void pop()
{
std::cout << "popping..." << std::endl;
std::cout << "popped: " << queue.pop() << std::endl;
}
int main()
{
std::thread consumerThread(pop);
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "main thread will push" << std::endl;
queue.push(2);
std::cout << "pushed" << std::endl;
consumerThread.join();
std::cout << "end" << std::endl << std::endl;
}
我的输出是:
...弹出
锁定pop()
主线程将推送
lock push()
推
锁定pop清醒。项目:1
从pop
返回弹出:2
端
答案 0 :(得分:4)
本声明:
cond_.wait(mlock);
实际上在等待期间解锁互斥锁,并在发出信号后重新获取锁定。这就是你没有任何僵局的原因。
答案 1 :(得分:3)
发生的事情是std :: condition_variable :: wait正在释放互斥锁。然后线程等待,直到notify_one调用,这将释放条件并重新获取互斥锁。
http://en.cppreference.com/w/cpp/thread/condition_variable/wait
“必须至少有一个线程正在等待条件变为true。等待线程必须首先获取unique_lock。此锁定传递给wait()方法,该方法释放互斥锁并挂起线程直到发出条件变量信号。当发生这种情况时,线程被唤醒并重新获取锁定。“ http://www.codeproject.com/Articles/598695/Cplusplus-threads-locks-and-condition-variables
答案 2 :(得分:0)
死锁需要在不同的线程中以不同的顺序获取两个互斥锁。我只在代码中看到一个互斥锁。