TIdHTTPServer.OnCommandGet 线程安全的内部使用全局原子变量吗?
Are global atomic variable used inside TIdHTTPServer.OnCommandGet threadsafe?
我试图更好地理解 Delphi Indy Server 和 ThreadSafe 变量。
假设我想要一个简单的计数器,用于计算 "hits" 到我的 Delphi Indy 网络服务器的数量。所以我声明一个全局整数
var: GlobalWebHits: Integer
在 TIdHttpServer.OnCommandGet 的处理程序中,我递增它:
procedure MyWebServer.CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
GlobalWebHits := GlobalWebHits+1;
.....
end;
这个实现在线程安全方面可以吗?是否有可能两个线程同时尝试更新 GlobalWebHits?
递增是否应该包含在临界区中?
没有原子变量这样的东西。操作可以是原子的,也可以不是。
GlobalWebHits := GlobalWebHits+1;
这个不是原子的。它具有独立的读取、修改和写入阶段。
您可以使用临界区,但使用原子操作更简单、更高效:
AtomicIncrement(GlobalWebHits);
或
TInterlocked.Increment(GlobalWebHits);
或
InterlockedIncrement(GlobalWebHits);
取决于您使用的 Delphi 版本。
我试图更好地理解 Delphi Indy Server 和 ThreadSafe 变量。
假设我想要一个简单的计数器,用于计算 "hits" 到我的 Delphi Indy 网络服务器的数量。所以我声明一个全局整数
var: GlobalWebHits: Integer
在 TIdHttpServer.OnCommandGet 的处理程序中,我递增它:
procedure MyWebServer.CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
GlobalWebHits := GlobalWebHits+1;
.....
end;
这个实现在线程安全方面可以吗?是否有可能两个线程同时尝试更新 GlobalWebHits?
递增是否应该包含在临界区中?
没有原子变量这样的东西。操作可以是原子的,也可以不是。
GlobalWebHits := GlobalWebHits+1;
这个不是原子的。它具有独立的读取、修改和写入阶段。
您可以使用临界区,但使用原子操作更简单、更高效:
AtomicIncrement(GlobalWebHits);
或
TInterlocked.Increment(GlobalWebHits);
或
InterlockedIncrement(GlobalWebHits);
取决于您使用的 Delphi 版本。