【问题标题】:A stranger problem about QTimer::singleShot一个关于 QTimer::singleShot 的奇怪问题
【发布时间】:2019-07-27 21:28:30
【问题描述】:

我编写了一个调用 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

【问题讨论】:

    标签: qt


    【解决方案1】:

    看起来像未定义的行为。关于为什么您可能会看到所描述的症状,请考虑您对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 完成并返回。但是仍然有一个超时未决,它也将尝试退出现在无效的QEventLoop。当您再次以Test(2) 调用Test 时,很有可能新的QEventLoop 将在与先前调用Test 相同的地址构造。最终结果是仍然挂起的超时使用的QEventLoop 地址变为“有效”。因此,您看到的两个值实际上来自调用 Test(1) 的两个超时事件。

    正如我在开始时所说的那样——未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 2019-08-28
      • 2021-08-27
      • 1970-01-01
      相关资源
      最近更新 更多