如果用同步编写Delphi代码来序列化对主VCL线程的访问,但是这个代码然后在非VCL应用程序中使用,它是否会与应用程序的主线程同步或根本没有效果?
示例:
procedure TMyThread.Execute;
begin
// ... other code
Synchronize(SomeMethod);
// ...
end;
我们假设
CheckSynchronize
线程会挂起在Synchronize(SomeMethod)行吗?
答案 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>