2

disconnect()代わりに、キューに入れられたシグナルが受信スレッドで引き続き配信されるという問題については考えていません。

Senderオブジェクトがスレッド 1 でシグナルを生成しており、スレッド 2 に を介してシグナルReceiverに接続されているスロットを持つオブジェクトがある場合を考えてみましょう。SenderQt::DirectConnection

さて、 ではReceiver::~Receiver()、オブジェクトがすでに (おそらく部分的に) 破壊されている間にシグナルが配信されないようにする必要があります。接続が直接であるため、スロットはいつでもスレッド 1 で呼び出すことができ、特にReceiverの特定の属性の破棄とベースの破棄の間に発生する可能性があり、QObject信号も切断されます。したがって、私の質問は次のようになります。

オブジェクトを破棄する前にスレッド 2 のオブジェクトSenderを切断するだけで十分ですか、それとも呼び出し中にスレッド 1 でシグナルが発信されないようにする必要がありますか?ReceiverReceiverdisconnect()

スレッド 1 が信号を送信している最中にある場合を考えています。たとえば、受信スロットの実行の一番上にあり、その瞬間にスレッド 2 でdisconnect()呼び出しが行われます。スレッド 1 がシグナルの配信を終了するのを (ミューテックスを介して) 待ってから、切断を実行し、それ以上のシグナル配信をブロックする場合disconnect()、すべて問題ありませんが、そうであるかどうかはわかりません。

4

1 に答える 1

4

はいdisconnect()connect()保護のためにミューテックスを使用しています。

disconnect()関数の最初の行は次のとおりです。

bool QMetaObjectPrivate::disconnect(const QObject *sender, int signal_index,
                                    const QObject *receiver, int method_index,
                                    DisconnectType disconnectType)
{
    if (!sender)
        return false;

    QObject *s = const_cast<QObject *>(sender);

    QMutex *senderMutex = signalSlotLock(sender);
    QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0;
    QOrderedMutexLocker locker(senderMutex, receiverMutex);

connect()関数の最初の行は次のとおりです。

bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
                                 const QObject *receiver, int method_index, int type, int *types)
{
    QObject *s = const_cast<QObject *>(sender);
    QObject *r = const_cast<QObject *>(receiver);

    QOrderedMutexLocker locker(signalSlotLock(sender),
                               signalSlotLock(receiver));

ドキュメントを確認すると、次のQObjectことがわかります。

注: このクラスのすべての関数は再入可能ですが、connect()、connect()、disconnect()、および disconnect() もスレッドセーフです。

編集

シグナルが送信されると、QMetaObject::activate 関数が呼び出され、送信者のオブジェクト ミューテックスがロックされます。

void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
                           void **argv)
{
     ...
     QMutexLocker locker(signalSlotLock(sender));
于 2013-05-17T09:20:33.013 に答える