在非 VCL 应用程序中使用同步是否危险



如果Delphi代码是用sync编写的,以序列化对主VCL线程的访问,但此代码随后用于非VCL应用程序,它会与应用程序的主线程同步还是根本没有效果?


例:

procedure TMyThread.Execute;
begin
  // ... other code
  Synchronize(SomeMethod);
  // ...
end;

让我们假设

  • 它是一个非VCL应用程序,其主线程在无限循环中执行(或直到终止(
  • 主线程不直接调用CheckSynchronize或在唤醒主线程处理程序中调用
  • 辅助线程运行并执行同步(SomeMethod(,如上例所示

线程会挂在同步(某种方法(行上吗?

TThread为非 VCL 程序提供了检查同步队列的工具,因此它们可以继续使用期望同步其方法的多线程库。这在 CheckSynchronize 的文档中进行了描述。请记住,检查队列是应用程序的工作,而不是库的工作。

只要应用程序遵守合同的其部分,您使用Synchronize应该没问题。但是,如果没有,那么您的程序将无法正常工作,但我不知道会出现什么确切的症状。绞刑听起来当然合理。

在非 VCL 应用程序中使用同步是否危险?

是的,这很危险。如果您的主线程未调用CheckSynchronizeSynchronize将导致死锁。

让我们假设

  • 它是一个非VCL应用程序,其主线程在无限循环中执行(或直到终止(
  • 主线程不直接调用CheckSynchronize或在WakeMainThread处理程序中调用
  • 辅助线程运行和执行Synchronize(SomeMethod)如上例所示

线程会挂在Synchronize(SomeMethod)线上吗?

Synchronize的调用将阻塞后台线程,直到主线程调用CheckSynchronize。因此,如果主线程从不调用CheckSynchronize,则后台线程将无限期阻塞。

以下程序对此进行了说明:

program TheBigSleep;
{$APPTYPE CONSOLE}
uses
  SysUtils, Classes, Windows;
type
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  end;
procedure TMyThread.Execute;
begin
  Synchronize(SysUtils.Beep);
end;
begin
  with TMyThread.Create do
    WaitForSingleObject(Handle, INFINITE);
    //don't call WaitFor since that, in turn, calls CheckSynchronize
end.

由于您将 Delphi 代码放在库中供其他应用程序使用,因此我不建议使用Synchronize(),因为您的线程对自身之外发生的事情没有概念。 更好的选择是让线程公开一个回调事件,线程可以在需要时在自己的上下文中调用该事件,然后让应用提供一个回调函数处理程序,该函数处理程序根据需要决定与应用的主线程同步的最佳方式。

最新更新