0

我不确定我的要求是否会产生任何影响。我显然是这方面的新手,但让我们假设我有一个对象:

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

我使用 disconnected 作为锁,因此如果客户端与服务器断开连接,它将不会对对象的任何字段执行任何操作。现在让我们假设有两个函数同时被两个线程访问:Thread1 和 Thread2

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 正在访问该对象的变量。

会发生什么?它会导致异常还是我只是假设一些事情(对不起,我一直在为我的服务器应用程序中发生的所有异常而烦恼)。如果是,那么释放对象的最安全方法是什么?

谢谢

4

1 回答 1

0

不要让这种情况发生——做 TCP 所做的事情。

不要仅仅因为它们断开连接就释放客户端对象。将它们放入“FreePending”增量队列中,然后只在之后释放它们,比如一分钟。到那时,任何其他可能引用断开连接的客户端对象的线程都将注意到断开连接状态并放弃它们的操作。

于 2013-05-29T17:04:02.583 回答