在每次循环迭代时停止代码执行毫秒

Stopping code execution for milliseconds at each iteration of loop

本文关键字:代码 执行 循环 迭代      更新时间:2023-10-16

我在循环中调用一个函数:

for (Item *item : *items) {
item->func();
}

被调用的函数发出信号并等待 100 毫秒:

void Item::func()
{
// Emit a signal
emit castSignal();
QTimer::singleShot(100 /* msec */, [](){
qDebug() << "Wait for 100 milliseconds";
});
}

我有一个插槽,当收到信号时记录到控制台:

QObject::connect(this, &Item::castSignal, this, &Item::handleSignal);
void Item::handleSignal()
{
qDebug() << "Signal received";
}

我希望日志是这样的:

Signal received
Wait for 100 milliseconds
Signal received
Wait for 100 milliseconds
Signal received
Wait for 100 milliseconds

但实际日志是这样的:

Signal received
Signal received
Signal received
Wait for 100 milliseconds
Wait for 100 milliseconds
Wait for 100 milliseconds

我想不通为什么!谁能帮忙。

singleShot添加一个计时器,然后继续执行。 时间间隔过后,将调用您的 lambda。 因此,您启动了三个计时器,并且在第一个计时器的超时时间过去之前接收到所有三个信号。

如果您确实需要等待 100 毫秒func请使用睡眠功能。

让我们一步一步地分析你的代码:

for (Item *item : *items) {
item->func();
}

相当于:

emit castSignal();
QTimer::singleShot(100 /* msec */, [](){
qDebug() << "Wait for 100 milliseconds";
});
emit castSignal();
QTimer::singleShot(100 /* msec */, [](){
qDebug() << "Wait for 100 milliseconds";
});
emit castSignal();
QTimer::singleShot(100 /* msec */, [](){
qDebug() << "Wait for 100 milliseconds";
});
// ...

必须考虑以下几点:

  • 在您的情况下,接收方和发送方开始相同的线程,因此由于默认情况下使用 Qt::AutoConnection ,因此会立即调用该插槽。

  • 定时器在同步部分结束时和指定时间启动

考虑到上述情况,看到handleSignal消耗的时间非常少,您的代码相当于:

qDebug() << "Signal received";
qDebug() << "Signal received";
qDebug() << "Signal received";
T: 100 ms
qDebug() << "Wait for 100 milliseconds";
qDebug() << "Wait for 100 milliseconds";
qDebug() << "Wait for 100 milliseconds";

获得您得到的行为。

@1201ProgramAlarm所指示的也是如此,但使用睡眠是一个糟糕的选择,因为它会阻塞事件循环,阻止其他信号、事件等正常运行,相反,一个可能的选择是使用 QEventLoop:

void Item::func()
{
// Emit a signal
emit castSignal();
QEventLoop loop;
QTimer::singleShot(100 /* msec */, [&loop](){
qDebug() << "Wait for 100 milliseconds";
loop.quit();
});
loop.exec();
}