假設我有一些類TMaster,它是一個包含TIdTCPServer的字段。 TMaster類的一些方法負責TIdTCPServer的OnExecute事件。Delphi(Indy)線程安全類
首先,這是線程安全和可接受的嗎?其次,讓我們假設我的類有許多其他私人領域(名稱,日期,任何...)可以OnExecute事件 - 這真的是一個方法內TMaster類,安全地寫入這些變量?
我想我的意思是問私人領域是否在這種情況下線程安全?
我真的很新,線程和任何幫助將不勝感激!
謝謝, 阿德里安!
假設我有一些類TMaster,它是一個包含TIdTCPServer的字段。 TMaster類的一些方法負責TIdTCPServer的OnExecute事件。Delphi(Indy)線程安全類
首先,這是線程安全和可接受的嗎?其次,讓我們假設我的類有許多其他私人領域(名稱,日期,任何...)可以OnExecute事件 - 這真的是一個方法內TMaster類,安全地寫入這些變量?
我想我的意思是問私人領域是否在這種情況下線程安全?
我真的很新,線程和任何幫助將不勝感激!
謝謝, 阿德里安!
我的做法,這不是有由事件使用的字段的方式屬於TidTCPServer
業主,但我創建一個自定義一個TidContext
後裔,並添加字段該類。
然後,您只需將服務器類上的ContextClass
屬性設置爲您的自定義上下文的類型即可。這樣,每個連接/線程將獲得自己的自定義上下文,其中包含自己的專用字段,這樣就沒有併發線程訪問相同字段的問題。
如果您有一個需要通過不同上下文訪問的對象列表,您有兩個選項。
1)創建複製對象並將它們存儲在每個上下文實例的專用字段中 這可以在OnConnect
事件中完成。
2)採用同步器例如TIdCriticalSection
,TMultiReadExclusiveWriteSynchronizer
或旗語保護從併發線程訪問的對象,
使用哪種方法取決於每個個體的情況。
如果您需要操作任何vcl組件,請記住,此操作無法安全地在主vcl線程之外完成,因此您應該爲此創建自己的tidnotify
後繼者。使用tidsynch
執行此類操作可能導致在tidtcpserver
(如果它處於vclsynch操作的中間)時導致死鎖。
這只是我在使用Indy的幾年中學到的一些東西。
TIdTCPServer
是一個多線程組件。無論您將其包裝在什麼中,OnExecute
事件將始終在工作線程的上下文中觸發,每個連接的客戶端都會觸發一個事件,因此您放入處理程序的任何代碼都必須是線程安全的。 TMaster
類的成員需要適當的保護,以免多個線程同時併發訪問。
那麼這是否意味着多個工作線程將執行這個OnExecute包裝的MULTIPLE實例? – Adrian 2012-07-25 04:11:15
@Adrian每個線程都會執行相同的OnExecute方法,但對於本地變量數據有自己的內存塊 – mjn 2012-07-25 06:34:15
服務器中的每個客戶端都將運行在其自己的唯一線程中。服務器只有一組「OnConnect」,「OnDisconnect」,「OnExecute」和「OnException」事件可用,任何客戶端可以隨時觸發這些事件。這些事件有一個參數來告訴你哪個客戶端正在觸發事件。所以是的,您可以並且通常會有多個客戶端同時運行相同的事件處理程序。這就是爲什麼你的事件處理程序的主體必須是線程安全的。如果事件處理程序訪問'TMaster'類的共享變量,則必須保護該變量。 – 2012-07-25 19:33:17
如果你的「TMaster類的某些方法」中的代碼是線程安全的,那麼它是線程安全的。換句話說,Indy在調用你的代碼之前是線程安全的。一旦開始到達,線程安全由您決定。這同樣適用於訪問您的私人領域。 – jachguate 2012-07-26 10:36:43