Multithreading Delphi:IdHTTPServer(Indy 10.6)在多线程上下文中共享变量的最佳实践

Multithreading Delphi:IdHTTPServer(Indy 10.6)在多线程上下文中共享变量的最佳实践,multithreading,delphi,indy,indy10,idhttp,Multithreading,Delphi,Indy,Indy10,Idhttp,我有一个TMyIdHTTPServer服务器对象扩展到了httpserver。我的TMyIdHTTPServer在多线程上下文中共享了一些私有变量(我认为TIdHTTPServer会为每个请求创建一个新线程) 我不是delphi或多线程编程专家,也不确定我的方法是否安全和/或是否具有良好的性能 当一些线程读取相同的变量时会发生什么情况,性能会下降?是否存在线程冲突的风险 基本示例: type TMyLogObject = class // write string LogM

我有一个TMyIdHTTPServer服务器对象扩展到了httpserver。我的TMyIdHTTPServer在多线程上下文中共享了一些私有变量(我认为TIdHTTPServer会为每个请求创建一个新线程)

我不是delphi或多线程编程专家,也不确定我的方法是否安全和/或是否具有良好的性能

当一些线程读取相同的变量时会发生什么情况,性能会下降?是否存在线程冲突的风险

基本示例:

type
    TMyLogObject = class
       // write string LogMessage in LogFilePath
       procedure WriteLog(const LogMessage, LogFilePath: string);
    end;

    TMyIdHTTPServer = class(TIdHTTPServer)
    private
       FMyLogObject : TMyLogObject;
       FLogPath     : string; 
       procedure  ServerStart;
       procedure  ServerStop;
       procedure  OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
       procedure  OnWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
    public
       constructor Create(const ConfigINI string); reintroduce;
    end;

implementation

   // ConfigINI is a absolute path of server_config.ini
   constructor Create(const ConfigINI string);
   var
     aConfigINI: TIniFile;
   begin
     inherited;

     aConfigINI := TIniFile.Create(ConfigINI);
     try
       // set the path of server log file
       FLogPath := FConfigINI.ReadString('CONFIG', 'LOG_PATH', '');
     finally
       aConfigINI.free;
     end;
   end;

   procedure TMyIdHTTPServer.ServerStart;
   begin
       self.Active  := True;
       FMyLogObject := TMyLogObject.Create;
   end;

   procedure TMyIdHTTPServer.ServerStop;
   begin
       self.Active  := False;
       FMyLogObject.Free;
   end;

   procedure TMyIdHTTPServer.OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
   begin
       AContext.Connection.OnWorkEnd := OnWorkEnd;

       FMyLogObject.WriteLog('StartRequest', FLogPath + 'log.txt');

       AResponseInfo.ContentText := 'Hello!';
   end;

   procedure TMyIdHTTPServer.OnWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
   begin
       FMyLogObject.WriteLog('EndRequest', FLogPath + 'log.txt');
   end;

多线程读取FLogPath没有问题。您将希望使您的TMyLogObject(或其使用)线程安全。如果您在没有任何锁定机制的情况下将条目转储到log.txt文件中,您最终会在日志中发现一个非常有趣的混乱文本。我只会在TMyLogObject的构造函数中传递一次日志文件路径和名称,而不是在每个日志中传递statement@AnthonyEischens正确的。。。谢谢@美赞臣对。。。谢谢TIdHTTPServer为每个请求创建一个新线程:并不是那么简单,在TIdHTTPServer中,请求和线程之间没有1:1的关系