c++ - QMutex:销毁锁定的互斥体

标签 c++ multithreading qt qtconcurrent qmutex

给定以下代码:

#include <chrono>
#include <ctime>
#include <functional>
#include <iostream>
#include <thread>
#include <utility>

#include <QFuture>
#include <QMutex>
#include <QWaitCondition>
#include <QtConcurrent>

class Async
{
public:
    Async() = default;
    Async(const Async&) = delete;
    Async(Async&&) = delete;

    ~Async() = default; //{ m_mutex.unlock(); }

    Async& operator=(const Async&) = delete;
    Async& operator=(Async&&) = delete;

    template<typename t_result>
    QFuture<bool> operator()(
          std::function<t_result()>&& p_function,
          std::chrono::milliseconds p_timeout,
          t_result* p_result)
    {
        QtConcurrent::run([this, p_function, p_result]() {
            *p_result = p_function();
            std::cout << time(nullptr) << " waking" << std::endl;
            m_cond.wakeAll();
    });

    return QtConcurrent::run([this, p_timeout]() {
           std::cout << time(nullptr) << " starting to wait for "
                     << p_timeout.count() << " ms" << std::endl;
           m_mutex.lock();
           bool wait =
               m_cond.wait(&m_mutex, 
                           static_cast<unsigned 
                                       long>(p_timeout.count()));
           std::cout << time(nullptr)
                     << ", finished waiting = " 
                     << (wait ? "T" : "F") 
                     << std::endl;
           if (wait) {
               return false;
           }
           return true;
    });
  }

private:
    QMutex m_mutex;
    QWaitCondition m_cond;
};

int main()
{
  Async async;

  char letter = 'z';

  std::function<char()> f1 = []() -> char {
      std::this_thread::sleep_for(std::chrono::seconds(4));
      return 'a';
  };

  std::cout << "1: " << time(nullptr) << std::endl;
  QFuture<bool> result =
    async(std::move(f1), std::chrono::milliseconds(3999), 
          &letter);

  std::cout << "2: " << time(nullptr) << std::endl;

  std::this_thread::sleep_for(std::chrono::seconds(8));

  std::cout << "3: " << time(nullptr) << std::endl;

  if (result.result()) {
    std::cout << "timeout, letter = " << letter;
  } else {
    std::cout << "NO timeout, letter = " << letter;
  }
  std::cout << std::endl;

  return 0;
}

最后... 8),当我运行它时,所有的cout 打印出预期的内容,但我得到一个QMutex: destroying locked mutex 在执行结束时。由于我收到消息 finished waitingm_cond.wait 被执行,因此(我认为)m_mutex 将被解锁。但似乎并非如此。

如果我使用 ~Async() { m_mutex.unlock(); ,我没有收到消息,但我认为不应该这样做。

谁能解释一下为什么互斥量没有被释放?

非常感谢!

最佳答案

当可运行的等待条件变量使用独占互斥锁时,它会在等待结束(超时或未超时)时持有互斥锁上的锁。

这意味着你必须显式解锁互斥量

bool wait = m_cond.wait(&m_mutex,static_cast<unsigned long>(p_timeout.count()));
m_mutex.unlock();
if (wait) {
    return false;
}
return true;

关于c++ - QMutex:销毁锁定的互斥体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54778058/

相关文章:

c++ - 优点和缺点...常量作为值还是作为引用?

java - 当我想从其头部删除消息时,如何在java中正确使用BlockingQueue

c# - 线程安全队列 - Enqueue/Dequeue

c++ - Qt/C++ : drawing efficiently

c++ - 当 QListView 选择因键盘事件而改变时发出信号?

C++ macOS - 以编程方式检索代码签名证书信息

c++ - 植绒算法在200个以上的物体上崩溃

c++ - 将 vector 拆分为多个数组/vector C++

python - 多线程文件复制比多核 CPU 上的单线程慢得多

c++ - 将 OpenGL 渲染保存到图像文件