2013-05-16 22 views
2

我不認爲隊列信號仍然傳送在接收線程disconnect()之後,而不是問題的:QObject :: disconnect()之後是否保證沒有信號從另一個線程傳遞?

考慮到一個Sender對象在線程1產生信號的情況下,有一個Receiver對象在螺紋2其中有一個插槽通過Qt::DirectConnection連接到Sender的信號。

現在,在Receiver::~Receiver()中,我需要確保在對象已經(可能部分)被破壞時仍然沒有信號被傳遞。因爲連接是直接的,所以可以隨時在線程1中調用該插槽,並且特別可以在破壞Receiver的特定屬性和破壞基礎QObject之間發生,這也將斷開信號。所以,我的問題歸結爲:

是否足夠給Receiver對象的破壞之前斷開的線2 SenderReceiver對象,或者我需要確保沒有信號的disconnect()在通話過程中的線程1發出?

我在考慮線程1處於發射信號的中間的情況,例如,就在執行接收槽的頂部,並且在那一刻,在線程2中,完成了disconnect()的調用。如果disconnect()等待(通過互斥體)線程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文檔,你可以看到:

注意:此類中的所有函數都是reentran t,但connect(), connect(),disconnect()和disconnect()也是線程安全的。

編輯

當信號發出的QMetaObject ::激活函數被調用其鎖定發件人的對象互斥:

void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index, 
          void **argv) 
{ 
    ... 
    QMutexLocker locker(signalSlotLock(sender)); 
+0

謝謝,是的,我看到了。我不確定的是信號的傳輸是否使用相同的互斥體進行保護。 –

+1

是的,他們是。檢查我更新的答案 – pnezis

相關問題