1

In Qt, how does one avoid race conditions if signals can be emitted around the same time when I connect to them?

Consider the following naïve example:

MySignalSender *sender = new MySignalSender(); // starts async operation that emits `fooSignal`
// <-- Possibility (1): `fooSignal` can be emitted here
MySignalReceiver *receiver = new MySignalReceiver();
// <-- Possibility (2): `fooSignal` can be emitted here
QObject::connect(sender, &MySignalSender::fooSignal, receiver, &MySignalReceiver::fooSlot);
// <-- Possibility (3): `fooSignal` can be emitted here or later

Since fooSignal is emitted from another thread, the choice of possibilities 1-3 is realized non-deterministically by the scheduler at runtime. While the desired behavior would only be achieved in the third case, in the remaining two we lose the signal, likely leading to a deadlock or some other undefined behavior.

Does Qt offer some atomic mechanism to temporarily pause signals from objects? I'm aware of QObject::blockSignals(), however my understanding is that this suppresses signals entirely rather than just postponing them for a while.

Thank you in advance!

4

1 回答 1

2

一种选择是简单地更改构建发送信号的对象的方式。您可以将对象的构造与异步操作的开始分开。

MySignalSender *sender = new MySignalSender();
MySignalReceiver *receiver = new MySignalReceiver();
QObject::connect(sender, &MySignalSender::fooSignal, receiver, &MySignalReceiver::fooSlot);

sender->startAsyncOperations();
于 2020-10-27T16:24:02.247 回答