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

mjn*_*mjn 13 delphi multithreading

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


例:

procedure TMyThread.Execute;
begin

  // ... other code

  Synchronize(SomeMethod);

  // ...

end;
Run Code Online (Sandbox Code Playgroud)

我们假设

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

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

Rob*_*edy 9

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

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


Dav*_*nan 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.
Run Code Online (Sandbox Code Playgroud)

  • +1,关于`Synchronize`,不要使用它.线程不应该依赖于它的范围之外的东西.最好使用非阻塞调用,如`PostMessage`或`TThread.Queue`.请参阅[mghie's](http://stackoverflow.com/users/30568/mghie)回答[是否更好地使用TThread的"同步"或在主线程和子线程之间使用IPC的IPC消息?](http:// stackoverflow .com/a/1806947/576719)摘要. (3认同)