2012-07-25 93 views
1

假設我有一些類TMaster,它是一個包含TIdTCPServer的字段。 TMaster類的一些方法負責TIdTCPServer的OnExecute事件。Delphi(Indy)線程安全類

首先,這是線程安全和可接受的嗎?其次,讓我們假設我的類有許多其他私人領域(名稱,日期,任何...)可以OnExecute事件 - 這真的是一個方法內TMaster類,安全地寫入這些變量?

我想我的意思是問私人領域是否在這種情況下線程安全?

我真的很新,線程和任何幫助將不勝感激!

謝謝, 阿德里安!

+0

如果你的「TMaster類的某些方法」中的代碼是線程安全的,那麼它是線程安全的。換句話說,Indy在調用你的代碼之前是線程安全的。一旦開始到達,線程安全由您決定。這同樣適用於訪問您的私人領域。 – jachguate 2012-07-26 10:36:43

回答

4

我的做法,這不是有由事件使用的字段的方式屬於TidTCPServer 業主,但我創建一個自定義一個TidContext後裔,並添加字段該類。

然後,您只需將服務器類上的ContextClass屬性設置爲您的自定義上下文的類型即可。這樣,每個連接/線程將獲得自己的自定義上下文,其中包含自己的專用字段,這樣就沒有併發線程訪問相同字段的問題。

如果您有一個需要通過不同上下文訪問的對象列表,您有兩個選項。

1)創建複製對象並將它們存儲在每個上下文實例的專用字段中 這可以在OnConnect事件中完成。

2)採用同步器例如TIdCriticalSectionTMultiReadExclusiveWriteSynchronizer或旗語保護從併發線程訪問的對象,

使用哪種方法取決於每個個體的情況。

如果您需要操作任何vcl組件,請記住,此操作無法安全地在主vcl線程之外完成,因此您應該爲此創建自己的tidnotify後繼者。使用tidsynch執行此類操作可能導致在tidtcpserver(如果它處於vclsynch操作的中間)時導致死鎖。

這只是我在使用Indy的幾年中學到的一些東西。

2

TIdTCPServer是一個多線程組件。無論您將其包裝在什麼中,OnExecute事件將始終在工作線程的上下文中觸發,每個連接的客戶端都會觸發一個事件,因此您放入處理程序的任何代碼都必須是線程安全的。 TMaster類的成員需要適當的保護,以免多個線程同時併發訪問。

+0

那麼這是否意味着多個工作線程將執行這個OnExecute包裝的MULTIPLE實例? – Adrian 2012-07-25 04:11:15

+0

@Adrian每個線程都會執行相同的OnExecute方法,但對於本地變量數據有自己的內存塊 – mjn 2012-07-25 06:34:15

+1

服務器中的每個客戶端都將運行在其自己的唯一線程中。服務器只有一組「OnConnect」,「OnDisconnect」,「OnExecute」和「OnException」事件可用,任何客戶端可以隨時觸發這些事件。這些事件有一個參數來告訴你哪個客戶端正在觸發事件。所以是的,您可以並且通常會有多個客戶端同時運行相同的事件處理程序。這就是爲什麼你的事件處理程序的主體必須是線程安全的。如果事件處理程序訪問'TMaster'類的共享變量,則必須保護該變量。 – 2012-07-25 19:33:17