QMutex:销毁锁定的互斥量
QMutex: destroying locked mutex
给定以下代码:
#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 waiting
,m_cond.wait
被执行,因此(我认为),m_mutex
将被解锁。但似乎并非如此。
如果我使用 ~Async() { m_mutex.unlock(); }
,我不会收到消息,但我认为不应该这样做。
任何人都可以解释为什么互斥量没有被释放吗?
非常感谢!
来自 Qt QMutex 页面:
Warning: Destroying a locked mutex may result in undefined behavior.
当 runnable 使用独占互斥体等待条件变量时,它会在等待结束(超时或未超时)时持有互斥体上的锁。
这意味着您必须显式解锁互斥体
bool wait = m_cond.wait(&m_mutex,static_cast<unsigned long>(p_timeout.count()));
m_mutex.unlock();
if (wait) {
return false;
}
return true;
给定以下代码:
#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 waiting
,m_cond.wait
被执行,因此(我认为),m_mutex
将被解锁。但似乎并非如此。
如果我使用 ~Async() { m_mutex.unlock(); }
,我不会收到消息,但我认为不应该这样做。
任何人都可以解释为什么互斥量没有被释放吗?
非常感谢!
来自 Qt QMutex 页面:
Warning: Destroying a locked mutex may result in undefined behavior.
当 runnable 使用独占互斥体等待条件变量时,它会在等待结束(超时或未超时)时持有互斥体上的锁。
这意味着您必须显式解锁互斥体
bool wait = m_cond.wait(&m_mutex,static_cast<unsigned long>(p_timeout.count()));
m_mutex.unlock();
if (wait) {
return false;
}
return true;