c++ - 为什么它不会发生死锁?

标签 c++ multithreading locking mutex

代码同时从两个不同的线程获取相同的互斥体。 我知道应该发生死锁。为什么没有发生?

#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;
}

我的输出是:

popping...

lock pop()

main thread will push

lock push()

pushed

lock pop awake. Items: 1

returning from pop

popped: 2

end

最佳答案

这个声明:

 cond_.wait(mlock);

实际上在等待期间解锁互斥锁,并在发出信号后重新获取锁。这就是您没有任何死锁的原因。

关于c++ - 为什么它不会发生死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27968838/

相关文章:

c++ - 调用多个 WinAPI 函数导致大约 30 个错误

c++ - 如何做类似 "is_atomically_assignable"的事情?

multithreading - 在Linux中的内核线程之间进行通信

java - 在 Java 的循环中使用 Thread.sleep() 定期做某事是否可以?

php - 执行 PHP 端锁定时如何选择锁定名称

c# - 在C++中实现锁

c++ - 转发声明/什么时候最好包含标题?

c++ - 如果没有人调用该函数,为什么我会得到 First-chance 异常?

python - 是否有多线程 map() 函数?

Python:在另一个线程修改字典时迭代字典