【问题标题】:Is TIdHTTP threadsafe?TIdHTTP 线程安全吗?
【发布时间】:2021-01-08 08:48:33
【问题描述】:

我在课堂上使用 TIdHTTP 来处理 Web API (TWebAPI)。由于可能会在 TIdHTTPServer.OnCommandGet 事件处理程序中使用此类,因此我需要确保 TWebAPI 是线程安全的。

我需要将PUT/GET/POST 包裹在TMultiReadExclusiveWriteSynchronizer 中吗?

编辑:代码示例

TWebAPI

TWebAPI=class(TObject)
 FSocket:TidHTTP;
end;

procedure TWebAPI.Send;
Var
 Response:TSTringStream;
begin
 FSocket.Get(fURL,Response);
end;

主程序

TMain=class(TForm)
 Server:TidHTTPServer;
 WebAPI:TWebAPI;
end;

procedure TMain.ServerCommandGet(....)
begin
 WebAPI.Send;
end;

所以我的 WebAPI 将在服务器获取的每个命​​令的不同线程中使用。我应该在 TMain 中使用 CriticalSection,还是像这样在 TWebAPI 中实现它?

TWebAPI=class(TObject)
 FSocket:TidHTTP;
 FLock:TCriticalSection;
end;

procedure TWebAPI.Send;
Var
 Response:TSTringStream;
begin
 FLock.Aquire;
 try
   FSocket.Get(fURL,Response);
 finally
   FLock.Release;
 end;
end;

【问题讨论】:

  • 这取决于你如何使用它。您没有显示任何代码。像大多数其他类一样,如果您跨线程边界共享TIdHTTP 对象,那么是的,您需要同步访问它。否则,不,你没有。请提供您关心的minimal reproducible example,有人可以告诉您它是否是线程安全的。
  • @RemyLebeau,添加代码 :-)
  • 您正在跨多个线程共享一个 TIdHTTP,所以是的,您需要在要执行的每个 HTTP 操作上锁定对它的访问。您是否有理由以这种方式使用单个 TIdHTTP,而不是让每个 TIdTCPServer 线程使用自己的本地 TIdHTTP
  • 您无需重复使用单个 TIdHTTP 就可以在多个 HTTP 请求中重复使用凭据。使用 1 TIdHTTP 一次获取凭证并保存,然后您可以根据需要将保存的凭证分配给其他 TIdHTTP 对象。所以,我仍然认为每个服务器线程都应该使用自己的本地TIdHTTP,并且您只在它们之间同步 OAuth 登录。
  • 您不能在多个客户端之间同时共享(SSL)IOHandler,因为它代表单个TCP 连接。但是,如果您有多个请求发送到同一个服务器,那么共享一个(SSL)IOHandler 可能是有意义的,只要这些请求不是同时 执行的。例如,您可以创建一个包含(SSL)IOHandler 对象的小池,然后在需要发出请求时从池中拉出一个,完成后将其放回池中。当然,你也可以对 TIdHTTP 对象做同样的事情。

标签: delphi indy10 idhttp


【解决方案1】:

单个 TIdHTTP 可以由 TCriticalSectionTMonitor 保护。不涉及 R/W,所以不要使用TMultiReadExclusiveWriteSynchronizer - 只是一个互斥锁/锁。但是,如果您使用单个 TIdHTTP,您将需要一个互斥锁/锁,因此所有 HTTP 调用都将被序列化,这在多线程服务器上可能不是一个好主意。

我会为每个线程维护一个连接,或者编写一个连接池。也许每次只是一个给定的 TIdHTTP 可能还不错。至少它会是安全的,以后会有改进的空间。实际上,重新打开 TCP/HTTP 连接很快。

【讨论】:

  • 我目前只使用TMREWS进行所有操作。一直使用它会丢失“只是”性能,还是有任何其他注意事项?
  • 可以使用TMREWSync,但你必须只使用它的写锁来获得足够的保护,这违背了最初使用TMREWSync的目的地方。 TCriticalSectionTMonitor,甚至是 Win32 Slim R/W Lock,会更有效。
猜你喜欢
  • 2020-04-15
  • 2011-07-04
  • 2014-04-26
  • 2012-11-30
  • 2010-12-30
  • 2013-03-12
  • 2021-08-03
  • 2010-12-27
  • 2018-06-04
相关资源
最近更新 更多