2011-11-19 53 views
1

所以,如果我理解正確的話,如果我有一個類FunctionsClass繼承QObject的,我設置等級可達上的QThread做稱爲FunctionClassThread混亂使用Qt線程

FunctionsClass classObj; 
classObj.moveToThread(&FunctionClassThread); 
FunctionClassThread.start(); 

據我瞭解這種方法設置一個線程只會處理FunctionsClass中插槽的執行,這意味着如果FunctionsClass中的插槽出於某種原因具有無限循環,則可以阻止運行FunctionsClass的線程。

所以我的問題是:我如何在一個線程上運行函數類的函數而不僅僅是插槽?有沒有一種方法可以將整個對象(函數,成員變量等)放置在線程上,以便僅執行整個對象中的代碼/數據?並且我理解線程如何處理插槽的執行是否正確?

回答

1

當你執行一個對象的方法時,它會在調用該方法的線程中執行。 QObject在哪裏生活並不重要。

如果你想調用一個方法,使它在另一個線程中異步執行,你將不得不處理這種情況,以便發佈消息,等待線程可用(可能很忙,它必須首先將控制權返回給事件循環),然後運行該方法。

這可以使用信號和插槽,通常的連接。如果您不想使用該機制,則可以使用QMetaObject,但您仍然必須將它們聲明爲插槽。如果使用Qt :: QueuedConnection調用靜態方法invokeMethod,將調用擁有該方法的對象所在的線程中的方法。您也可以將參數傳遞給方法並從中返回值。

考慮到您希望能夠從一個線程傳遞到另一個線程的任何數據類型都需要使用qRegisterMetaType進行註冊,並且必須遵守其中報告的條件。

0

類的方法將在調用它們的線程的上下文中執行。如果你將一個QObject類移動到一個線程中(讓我們把它稱爲工作者線程),那麼只有該工作線程的run()方法直接(或間接)調用的那個類的方法纔會在工作者的上下文中執行線。

如果您想從其他線程調用該類的方法,但仍然讓它們在工作線程的上下文中運行,那麼您需要某種方式向工作線程傳遞消息,以便它可以調用方法你要。這實際上是在跨越線程邊界時由Qt信號和槽實現的。

隨着大量額外的工作,還有兩種其他方式可以做同樣的事情。首先,如果您不覆蓋run(),則QThread有一個默認啓動的事件循環。您可以創建custom events,您可以發佈到事件循環中,這可以觸發您的類中將在工作線程上下文中執行的活動。

第二種方法是從另一個修改工作線程監視的類字段的線程調用您的類中的方法。您需要確保對這些字段中的任何一個的訪問都與某個像互斥鎖一樣的機制同步。