gpt4 book ai didi

multithreading - Delphi:是否应该创建线程 "not suspended"?

转载 作者:行者123 更新时间:2023-12-03 14:43:26 25 4
gpt4 key购买 nike

我一直在尝试追踪 Jedi VCL 的 JvHidControllerClass.pas 中的内存泄漏,我在源代码历史记录中发现了此更改:

旧版本:

constructor TJvHidDeviceReadThread.CtlCreate(const Dev: TJvHidDevice);
begin
inherited Create(True);
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
end;

当前修订版:

constructor TJvHidDeviceReadThread.CtlCreate(const Dev: TJvHidDevice);
begin
inherited Create(False);
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
end;

根据经验,我发现如果您创建一个暂停的线程:

inherited Create(False);

然后线程立即开始运行。在这种情况下,它将尝试访问尚未初始化的对象:

procedure TJvHidDeviceReadThread.Execute;
begin
while not Terminated do
begin
FillChar(Report[0], Device.Caps.InputReportByteLength, #0);
if Device.ReadFileEx(Report[0], Device.Caps.InputReportByteLength, @DummyReadCompletion) then

立即尝试填充Report,并访问对象Device。问题是它们还没有初始化;这些是线程启动后的行:

  Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);

我意识到这是一个竞争条件;并且用户在生产中遇到崩溃的可能性非常低,因此离开竞赛崩溃可能是无害的。

但是我还差得远吗?我错过了什么吗?是否调用:

BeginThread(nil, 0, @ThreadProc, Pointer(Self), Flags, FThreadID);

不启动线程并立即运行?这真的是(故意)添加到 JVCL 的竞争条件回归吗?难道有什么 secret 吗

CreateSuspended(False);

这使得它成为正确的代码:

CreateSuspended(True);
...
FDataThread.Resume;

因错误调用而被烧伤后

TMyThread.Create(False)

我已经把它记在脑子里了,因为从来没有正确。让线程立即启动(当您必须初始化值时)是否有任何有效用途?

最佳答案

这是 TThread 的 Delphi 5 实现的一个基本设计缺陷。底层 Windows 线程在 TThread 的构造函数中启动。这导致了您所描述的比赛。

在Delphi 6版本的RTL中,线程启动机制发生了变化。从 Delphi 6 开始,线程在 TThread.AfterConstruction 中启动。它在构造函数完成后运行。这将使您的代码免于竞争。

在 Delphi 6 及更高版本中,底层 Windows 线程在 TThread 构造函数中创建,但使用 CREATE_SUSPENDED 标志挂起创建。然后在 AfterConstruction 中,只要 TThread.FCreateSuspishedFalse,线程就会恢复。

在 Delphi 5 中解决该问题的一种方法是最后调用继承的构造函数。像这样:

constructor TJvHidDeviceReadThread.CtlCreate(const Dev: TJvHidDevice);
begin
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
inherited Create(False);
end;

我知道相当丑陋。

因此,创建线程挂起并在构造函数完成后恢复的方法可能更好。这种方法反射(reflect)了 RTL 如何解决 Delphi 6 及更高版本中的问题。

关于multithreading - Delphi:是否应该创建线程 "not suspended"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17748365/

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