为什么它不会发生死锁
Why it does NOT occur deadlock?
代码同时从两个不同的线程获取相同的互斥锁。我知道应该出现僵局。为什么没有发生?
#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;
}
我的输出是:
啪......
锁定弹出()
主线程将推送
锁定按钮()
推
锁定弹出唤醒。商品: 1
从流行音乐归来
弹出:2
结束
此语句:
cond_.wait(mlock);
实际上在等待期间解锁互斥锁,并在发出信号后重新获取锁。这就是为什么你没有任何僵局。
正在发生的事情是 std::condition_variable::wait 正在释放互斥锁。然后,线程会等到notify_one调用,这将释放条件并重新获取互斥锁。
http://en.cppreference.com/w/cpp/thread/condition_variable/wait
"必须至少有一个线程正在等待条件变为真。等待线程必须首先获取unique_lock。此锁传递给 wait() 方法,该方法释放互斥锁并挂起线程,直到条件变量发出信号。当这种情况发生时,线程被唤醒,锁被重新获取。http://www.codeproject.com/Articles/598695/Cplusplus-threads-locks-and-condition-variables
死锁要求在不同的线程中以不同的顺序获取两个互斥锁。我只在您的代码中看到一个互斥锁。
相关文章:
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 使用 std::async 时死锁,将来作为成员
- 如何调试读写器锁的死锁?
- 为什么在Visual Studio 2013上的std::this_thread::sleep_for上死锁
- localtime() 函数正在调用 ___lll_lock_wait_private(),这会使线程陷入死锁
- 如何重现 Boost 进程文档提示的死锁?
- 多线程Windows GUI应用程序中的死锁
- 为什么printf会导致与future.get的死锁,而cout则不会?
- C++中具有阻塞队列和障碍的死锁
- 死锁使用 std::mutex 来保护多个线程中的 cout
- 避免并发等待对象中的死锁
- 在VC++中从DLLMAIN内部调用D3D的CREATEDEVICE时,它会创建一个死锁(loaderlock?)。有没有办法克服这个问题?最终目标内
- 当用2个螺纹锁定时,将recursive_mutex死锁
- 程序在 C++11 中使用条件变量进入死锁
- 为什么我的程序在拥有线程的情况下生成LdrpLoaderLock死锁
- 为什么从 DLL 调用 boost::wave::上下文构造函数时会死锁
- 为什么在下面的线程安全堆栈实现中没有死锁
- 为什么 lock() 在死锁的情况下不抛出异常