2012-12-19 47 views
11

dan yöntemi yürütürken QMetaObject :: invokeMethod kullanarak Neden:kod var aşağıdaki iplik

class A : public QObject 
{ 
    Q_OBJECT 
public: 
    A() : QObject() 
    { 
     moveToThread(&t); 
     t.start(); 
    } 
    ~A() 
    { 
     t.quit(); 
     t.wait(); 
    } 

    void doSomething() 
    { 
     QMetaObject::invokeMethod(this,"doSomethingSlot"); 
    } 
public slots: 
    void doSomethingSlot() 
    { 
     //do something 
     emit ready(); 
    } 
signals: 
    void ready(); 
private: 
    QThread t; 
} 

o QMetaObject::invokeMethod aracılığıyla çağrı edilmelidir neden doSomething gelen bir soru. Bağlantı tipi olan bir şey olduğunu biliyorum. Birisi kaputun altında ne olduğunu açıklayabilir mi? Bir Qt::ConnectionType belirtilmemiş gibi

+1

ecatmur size mükemmel bir cevap verdi. Başka bir probleminiz var, bu iş parçacığına taşınan nesnenin bir üyesi olarak iş parçacığı olması, imha sırasında (deleteLater kullanırken) çok tuhaf sorunlar olabilir. –

+0

Tam açıklama için [bu belge] okuyun (http://doc.qt.digia.com/4.2/threads.html#per-thread-event-loop) –

+0

@MarekR: Hangi problemler? Bu çözümü http://stackoverflow.com/questions/13878745/correct-way-of-threading-in-qt – krzych

cevap

23

, yöntem nesnenin iplik afinite mevcut iplik ise, o (normal bir işlev çağrısı gibi) eş zamanlı olarak çağrılır yani, Qt::AutoConnection olarak çağrılan ve senkronize olmayan edilecektir aksi takdirde. "Eşzamansız", QEvent'un ileti sırasına göre oluşturulduğu ve iletildiği anlamına gelir ve olay döngüsü ona ulaştığında işlenecektir.

QMetaObject::invokeMethod, alıcı nesnesi başka bir iş parçacığında olabilirse, başka bir iş parçacığı üzerinde doğrudan bir nesne üzerinde bir yuva aramayı denemenin, iş parçacığı için güvenli olmayan verilere erişmesi veya bunları değiştirmesi durumunda bozulmaya veya daha kötü duruma yol açmasıdır.

+0

Yani bir başka iş parçacığından A.doSomething() kullanırsam yolsuzluğa neden olabilir mi? Neden öyle? Mekanizmayı da tarif edebilir misiniz? – krzych

+1

@krzych örneğin, bir QString'den aynı anda okuyorsanız, başka bir iş parçacığı değiştiriyorsa, tutarsız bir durumda olduğu gibi, tutarsız bir durumda dolaylı olarak görünebilir. – ecatmur

18

ben bu hileyi gibi:

void A:doSomethingSlot() 
{ 
    if (thread()!=QThread::currentThread()) { 
     QMetaObject::invokeMethod(this,"doSomethingSlot", Qt::QueuedConnection); 
     return; 
    } 
    // this is done always in same thread 
    ... 
    emit ready(); 
}