gpt4 book ai didi

multithreading - Delphi中检测辅助线程上下文

转载 作者:行者123 更新时间:2023-12-03 15:17:37 26 4
gpt4 key购买 nike

在 Delphi 2009 和 Windows API 中,有没有办法检测特定代码段是否在辅助线程的上下文中运行?在伪代码中,我希望能够说:

procedure DoSomething;
begin
if InvokedBySecondaryThread then
DoIt_ThreadSafeWay
else
DoIt_RegularWay;
end;

这是我编写并使用多年的日志库,现在正在尝试适应可以从多个线程调用一个过程的情况。我的“常规方式”不是线程安全的。我知道如何使其线程安全,但我想仅在实际需要时才使用线程安全方法。

解释(不是必读:-)

它归结为使用 SendMessage 和 PostMessage 将记录的消息分派(dispatch)到多个接收器(例如日志文件、控制台或 VCL 控件)之间的选择。使用 PostMessage 意味着在进行长时间阻塞操作时将不会收到消息,这在某种程度上违背了日志记录的目的,尤其是。当用于表示进度时。我想我可以使用关键部分来保护 SendMessage 调用,但我还是更愿意仅在真正需要时才这样做。

我知道 system.pas 中的全局变量 IsMultiThread,但这只会告诉我应用程序已启动辅助线程。这些可能是由第三方库创建的线程,因此它们永远不会访问“我的”代码,因此它们的存在不会影响我的日志逻辑。

我真的希望能够使用相同的低级库代码,无论它是从一个线程还是多个线程调用。例如,从辅助线程内部调用修改后的线程安全日志记录过程很容易,但这会重复很多代码,而且我仍然必须记住始终做正确的事情。

@Lieven:目前,日志记录逻辑是这样的,有些简化

我希望日志记录尽可能轻松,使用最少的设置代码,并且不用担心管理对象生命周期,因此该库仅公开一些重载的帮助程序,例如

procedure Log( const msgText : string; level : TLogLevel = lvNotice ); overload;
procedure Log( const msgText : string; Args : array of const; level : TLogLevel = lvNotice ); overload;
etc, including specialized routines that log a StringList, a boolean, an Exception and so on

几乎所有其他事情都发生在该单元的实现中。所有辅助例程最终都会调用

procedure _LogPostMessage( const msgText : string; level : TLogLevel );

其中 (a) 检查单例调度程序对象是否已初始化; (b) 创建 TLogMessagePacket 对象的实例(消息文本、时间戳等的容器),最后 (c) 执行 SendMessage 或 PostMessage 将“数据包”发送到调度程序(调度程序有一个窗口句柄来接收它) )。

然后有一组从抽象 TLogReceiver 类派生的类。其中一个类接收记录的消息并将它们写入文件,另一个类更新 TMemo 等。我实例化我想要在项目中使用的具体接收器,并向调度程序注册它们,从那时起调度程序就拥有它们。

当调度程序收到消息“数据包”时,它会依次将其传递给每个接收者,然后释放它。

所以我可能固定在上述思维方式中,这就是为什么当你说将调度程序对象传递给日志库的代码应该根据线程上下文选择一个时我不太明白你的想法。调度程序实际上是库的主要引擎,并且一次仅存在一个。

最佳答案

  if GetCurrentThreadID = MainThreadID then begin
// in main thread
end
else begin
// in secondary thread
end;

关于multithreading - Delphi中检测辅助线程上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4097742/

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