2011-10-17 126 views
1

在C++中執行以下操作的最佳方式是什麼?雖然我目前的方法效果我不知道這是去的最佳途徑:將「this」傳遞給線程C++

1)我有一個其中有

2)一些函數級的高手我有一個線程,呈現出一些指令插座,然後運行在主類的功能的一個

3)有許多線程的訪問的各種功能在主類

我創建主類,然後創建從線程類的實例大師。線程類的構造函數傳遞給master的「this」指針。然後,我可以在線程內部的主類中運行函數 - 即,我得到一個命令來執行一些在線程中在主類中運行函數的功能。我有互斥等等,以防止種族問題。

我對這種錯誤的方式 - 它看起來像線程類應該繼承主類或另一種方法將不具有單獨的線程類,但只有他們作爲主類的功能,但變得醜陋。

+1

你能發表一些代碼嗎?你知道類和實例之間的區別嗎?每個線程是否有一個主類實例? –

+0

不,有一個主線程從中產生線程。線程只需要訪問主成員函數和一些變量 –

回答

1

聽起來不錯。在我的服務器中,它被稱爲'SCB' - ServerControlBlock - 並提供對IOCPbuffer /套接字池,記錄器,用於狀態/錯誤消息的UI訪問等服務的訪問以及所有處理程序線程需要公用的任何其他服務。工作正常,我不認爲它是一個破解。

在創建使用SCB的線程池之前,我創建了SCB(並確保在ctor中通過它訪問的所有服務都已啓動並可以使用) - 沒有討厭的單例東西。

Rgds, Martin Martin

+0

好聽起來不錯 - 我會繼續在我的線程池中使用「this」。 –

1

單獨的線程類是非常正常的,特別是如果他們有特定的功能。我不會從主線程繼承。

+0

是的我猜我的主要問題是將「this」指針傳遞給線程類錯誤編碼或者它是相當標準的。這感覺就像是一個黑客 –

+0

這是不是一個黑客,如果你把主類作爲單身人士等 –

+0

傳遞「這個」指針是正常的,這是一個常見的事情要做。正如Aditya所說,你也可以讓你的主類成爲單例,所以你不會傳遞任何指針,只要你想要訪問方法就調用MainClass :: getInst() - >。 –

1

薪火this指針線程不,本身不好。你用它做什麼可以。

this指針就像任何其他POD肥胖型的數據類型。這只是一小塊。然而,在this中的內容可能比POD更多,而傳遞實際上指向其成員的指針對於所有通常的原因可能是危險的。任何時候你在線程之間共享任何東西,都會引發潛在的競爭條件和死鎖。當然,解決這些衝突的基本手段是以互斥體,信號量等形式引入同步,但這可能會帶來序列化應用程序的驚喜效果。

說您從一個插座具有一個線程讀取數據並將其存儲到同步命令緩衝區,而另一個線程從該命令緩衝區讀取。兩個線程都使用相同的互斥鎖來保護緩衝區。一切都很好,對嗎?

好吧,也許不是。如果你不太關心你如何鎖定緩衝區,你的線程可能會被序列化。假設您爲緩衝區插入和緩衝區移除代碼創建了單獨的線程,以便它們可以並行運行。但是,如果您每次刪除每個插入的鎖定緩衝區,則一次只能執行其中一個操作。只要你寫入緩衝區,你就不能讀取它,反之亦然。

您可以嘗試微調的鎖,讓他們儘可能簡短,但只要你有共享,同步數據,你將有一定程度的系列化。

另一種方法是一手數據給另一個線程明確,並刪除儘可能多的數據共享成爲可能。例如,您的套接字代碼可能會在堆上創建某種Command對象(例如Command* cmd = new Command(...);),並將該對象傳遞給另一個線程,而不是像上面那樣寫入緩衝區並從緩衝區讀取數據。 (在Windows中執行此操作的一種方法是通過QueueUserAPC機制)。

有優點缺點&這兩種方法。同步方法具有在表面理解和實現起來更簡單的好處,但是如果你搞砸了,則更難以調試的潛在缺陷。切換方法可能使同步中固有的許多問題變得不可能(從而實際上使其更容易),但是在堆上分配內存需要時間。