qt - 一个关于 QTimer::singleShot 的奇怪问题
问题描述
我写了一个调用 QTimer::singleShot 的函数来确保它不应该超时。但我得到了一个奇怪的结果。
int Test(int x)
{
QEventLoop loop;
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&](){
loop.exit(x);
});
timer.start(7000);
QTimer::singleShot(10000, std::bind(&QEventLoop::exit, &loop, 3));
return loop.exec();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << Test(1) << endl;
qDebug() << Test(2) << endl;
return a.exec();
}
我希望输出为 1 2 但实际输出为 1 3
解决方案
看起来像未定义的行为。关于为什么您可能会看到所描述的症状,请考虑您的实施Test
......
int Test(int x)
{
QEventLoop loop;
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&](){
loop.exit(x);
});
timer.start(7000);
QTimer::singleShot(10000, std::bind(&QEventLoop::exit, &loop, 3));
return loop.exec();
}
您构建一个本地QEventLoop
. 然后,您设置了两个都退出本地事件循环的计时器回调(7 秒和 10 秒之后) 。第一次超时将退出导致Test
完成并返回的循环。但是仍然有一个超时未决,它也将尝试退出 now invalid QEventLoop
。当您Test
再次调用时,Test(2)
很有可能QEventLoop
在与上一次调用相同的地址构造新的Test
。最终结果是QEventLoop
仍然挂起的超时使用的地址变为“有效”。因此,您看到的两个值实际上来自调用Test(1)
.
正如我在一开始所说的那样——未定义的行为。
推荐阅读
- node.js - 如何使用节点 js 和套接字 io 对一个客户端发送到另一个客户端的消息进行端到端加密?
- c++ - 重载大于运算符并使用它来查找数组中的最大值
- mysql - MySQL ON UPDATE CURRENT_TIMESTAMP 更新所有行中的时间戳字段?
- wordpress - 页面作为具有自定义永久链接结构的存档不起作用
- asp.net - 调试部署在本地 IIS 上的 .net 核心应用程序?
- python - 使用 Pymongo 从 MongoDB 恢复二进制数据
- java - 将十六进制字符串转换为 Long 时出现 NumberFormatException
- react-admin - 使用 CustomApp 时在路由中列出和编辑组件所需的道具
- android - 带有 YouTubeBaseActivity 的 onFilterTouchEventForSecurity 中的 NullPointerException
- javascript - 如何将数据添加到 Google 表格图表