2013-05-29 60 views
0

我不知道我問的是否會產生任何影響。我清楚這個東西是一個新手,但讓我們假設我有一個對象:Delphi7多線程混淆

TClientInfo = class(TObject) 
    Username: TIdThreadSafeString; 
    UserID: TIdThreadSafeInteger; 
    Status: TIdThreadSafeInteger; 
    Disconnected: TIdThreadSafeBoolean; 
End; 

我使用斷開的鎖,所以如果客戶端與服務器斷開連接它不會做任何的任何操作對象的字段。現在,讓我們假設有被同時由兩個線程訪問兩個功能:線程1和線程

function client_disconnected() 
var Client: TClientInfo; 
begin 
    Client := FindClient(someusername); 
    Client.Disconnected.Lock; 
    Try 
    Client.Disconnected.Value := True; 
    Some operations...... 
    Finally 
    Client.Disconnected.Unlock; 
    FreeAndNil(Client.Disconnected); 
    FreeAndNil(Client); 
    End; 
end; 

的斷開例程來鎖定斷開可變其值設置爲true,並且執行操作,它釋放的端斷開的變量和對象(保留其他變量)。

現在還有這等功能:

function someoperations() 
Var Client: TClientInfo; 
begin 
    Client := FindClient(somename); 
    Client.Disconnected.Lock; 
    Try 
    If Client.Disconnected.Value = True Then Exit; 
    some operations..... 
    Finally 
    Client.Disconnected.Unlock; 
    End; 
end; 

現在兩個線程訪問都在同一時間的功能,客戶端斷開了,線程1鎖定斷開的變量,而線程2試圖鎖定斷開連接的變量用於操作,同時等待斷開連接例程被執行並且斷開連接的變量被解鎖。現在同時Thread1試圖釋放對象及其變量,而Thread2正在訪問該對象的變量。

會發生什麼?它會導致異常還是我只是假設事情(對不起,我一直在我的服務器應用程序中發生所有異常)。如果是的話,那麼釋放物體最安全的方法是什麼?

謝謝

回答

0

不要讓這發生 - 做TCP做的事情。

不要因爲客戶端連接斷開而釋放客戶端對象。把它們放在一個'FreePending'三角形隊列中,並且只在一分鐘後釋放它們。屆時,任何其他可能引用斷開連接的客戶端對象的線程都將注意到斷開狀態並放棄其操作。

+1

我喜歡等待的想法,但不是等待一分鐘的想法,並希望當時所有線程都會注意到。這隻會讓你的錯誤不那麼常見,而且更難以調試。而是保留一個指向連接的線程數的計數器,並在該refcount達到零後立即釋放它。 – GolezTrol