Qtの信号とスロットが異なるスレッド間で実行されてプログラムがクラッシュするのをどのように解決するか?
Qtは、シグナルスロットがスレッド間で行われる場合に、スレッドの安全を確保するための仕組みを用意しています。スレッド間のシグナルスロットを使用中にプログラムがクラッシュしてしまう場合は、以下の方法を試して問題を解決してください:
- Qt::QueuedConnection
- Qt::QueuedConnection
connect(sender, SIGNAL(signal()), receiver, SLOT(slot()), Qt::QueuedConnection);
- QMetaObject::invokeMethod()
- `QMetaObject::invokeMethod()`
QMetaObject::invokeMethod(receiver, "slot", Qt::QueuedConnection);
- マルチスレッドのプログラムでは、異なるスレッド間のシグナルとスロットを結び付ける中間オブジェクトを作成できます。中間オブジェクトは、適切なタイミングでターゲットオブジェクトにシグナルを転送できます。
void Intermediate::forwardSignal()
{
emit signal();
}
// 在连接信号和槽时使用中间对象
connect(sender, SIGNAL(signal()), intermediate, SLOT(forwardSignal()), Qt::QueuedConnection);
connect(intermediate, SIGNAL(signal()), receiver, SLOT(slot()), Qt::QueuedConnection);
- ネイティブスレッドセマフォ
- QReadWriteLock
- ネイティブな日本語で言い換える:QMutex
- ネイティブ読み書きロック
QMutex mutex;
// 线程1中的槽函数
void Object::slot()
{
mutex.lock();
// 访问共享数据
mutex.unlock();
}
// 线程2中的槽函数
void Object::slot()
{
mutex.lock();
// 访问共享数据
mutex.unlock();
}
上記のやり方を使えば、信号スロットのクロススレッド時のクラッシュが回避され、スレッドセーフな信号スロット呼び出しが可能になります。