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

时间:2012-05-21 16:42:07

标签: multithreading delphi

如果用同步编写Delphi代码来序列化对主VCL线程的访问,但是这个代码然后在非VCL应用程序中使用,它是否会与应用程序的主线程同步或根本没有效果?


示例:

procedure TMyThread.Execute;
begin

  // ... other code

  Synchronize(SomeMethod);

  // ...

end;

我们假设

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

线程会挂起在Synchronize(SomeMethod)行吗?

3 个答案:

答案 0 :(得分:9)

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

只要应用程序遵守合同的一部分,您对Synchronize的使用应该没问题。但是,如果它没有,那么你的程序将无法正常工作,但我不知道预期的确切症状。悬挂当然听起来似乎有道理。

答案 1 :(得分:6)

  

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

是的,它很危险。如果您的主线程未调用CheckSynchronize,那么Synchronize将导致死锁。

  

我们假设

     
      
  • 它是一个非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.

答案 2 :(得分:1)

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