gpt4 book ai didi

multithreading - 通过现有对象写入多线程文件

转载 作者:行者123 更新时间:2023-12-03 18:10:41 24 4
gpt4 key购买 nike

应用说明:

我有一个应用程序允许用户通过线程运行多个并发查询(一次最多 100 个)。

我有一个用于记录错误的类。如果应用程序中出现错误,我会创建该类的一个实例并调用一个过程将错误写入日志文件。

问题:

我需要使错误记录代码线程安全。我注意到如果很多线程同时运行并产生相同的错误(例如无法连接到数据库),我会收到 i/o 错误 32(由应用程序试图写入一个文件引起的)已经打开)。

作为一个快速而肮脏的修复,我将写入文件的代码放在一个 try...except block 中的一个 repeat 循环中。如果出现异常(例如,该文件已被该类的另一个实例打开,被另一个线程启动),则它会将标志设置为“false”。循环继续执行,直到标志为“真”(即写入文件没有错误),如下:

procedure TErrorLogging.logError(error: string);
var
f: textfile;
ok: boolean;
begin
repeat
ok := true;
try
assignfile(f, fLogFilename);
if fileExists(fLogFilename) then append(f) else rewrite(f);
writeln(f, error);
closefile(f);
except
ok := false;
end;
until ok;
end;

我知道保护代码块的正确方法是使用关键部分,但我不确定如何实现它,因为有许多不同的线程使用日志记录类,并且线程的每个实例都有自己的用于写入文件的日志类实例(因此它们不只是针对同一代码块进行同步)。

选项,如我所见:

  1. 使用上面的代码。保留此代码是否有任何问题?这是一个快速而肮脏的修复方法,但它确实有效。
  2. 使用全局 TCriticalSection(如何?)。
  3. 在某处使用单个过程来创建日志记录类的实例,线程将针对该实例进行同步(我想这会破坏拥有日志记录类的目标)。

最佳答案

每当您想附加日志条目时创建日志记录类的实例都是错误的,而且一遍又一遍地打开和关闭日志文件。我个人会使用一个类的一个实例,该类在内部使用字符串列表并且其基本方法是线程安全的。像这样:

type
TErrorLog = class
private
FList: TStringList;
FLock: TRTLCriticalSection;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
procedure Add(const ErrorText: string);
procedure SaveToFile(const FileName: string);
end;

implementation

{ TErrorLog }

constructor TErrorLog.Create;
begin
inherited Create;
InitializeCriticalSection(FLock);
FList := TStringList.Create;
end;

destructor TErrorLog.Destroy;
begin
EnterCriticalSection(FLock);
try
FList.Free;
inherited Destroy;
finally
LeaveCriticalSection(FLock);
DeleteCriticalSection(FLock);
end;
end;

procedure TErrorLog.Clear;
begin
EnterCriticalSection(FLock);
try
FList.Clear;
finally
LeaveCriticalSection(FLock);
end;
end;

procedure TErrorLog.Add(const ErrorText: string);
begin
EnterCriticalSection(FLock);
try
FList.Add(ErrorText);
finally
LeaveCriticalSection(FLock);
end;
end;

procedure TErrorLog.SaveToFile(const FileName: string);
begin
EnterCriticalSection(FLock);
try
FList.SaveToFile(FileName);
finally
LeaveCriticalSection(FLock);
end;
end;

关于multithreading - 通过现有对象写入多线程文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15644099/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com