gpt4 book ai didi

multithreading - 从其他线程访问 VT 数据是否安全?

转载 作者:行者123 更新时间:2023-12-03 15:26:07 24 4
gpt4 key购买 nike

从辅助线程更改 VirtualTreeView 数据是否安全?如果是,我应该使用关键部分(甚至同步方法)吗?

我担心当我从另一个线程写入VT的数据记录时,主线程同时调用其重绘,并且此刷新将导致同时读取同一记录。我想补充一下,我在应用程序中只使用了 2 个线程。

类似于...

type
PSomeRecord = ^TSomeRecord;
TSomeRecord = record
SomeString: string;
SomeInteger: integer;
SomeBoolean: boolean;
end;

...
var FCriticalSection: TRTLCriticalSection; // global for both classes
...

procedure TMyCreatedThread.WriteTheTreeData;
var CurrentData: PSomeRecord;
begin
EnterCriticalSection(FCriticalSection); // I want to protect only the record

CurrentData := MainForm.VST.GetNodeData(MainForm.VST.TopNode);

with CurrentData^ do // I know, the ^ is not necessary but I like it :)
begin
SomeString := 'Is this safe ? What if VT will want this data too ?';
SomeInteger := 777;
SomeBoolean := True;
end;

LeaveCriticalSection(FCriticalSection);

MainForm.VST.Invalidate;
end;

// at the same time in the main thread VT needs to get text from the same data
// is it safe to do it this way ?

procedure TMainForm.VST_GetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: string);
var CurrentData: PSomeRecord;
begin
EnterCriticalSection(FCriticalSection); // I want to protect only the record

CurrentData := VST.GetNodeData(VST.TopNode);

with CurrentData^ do
begin
case Column of
0: CellText := SomeString;
1: CellText := IntToStr(SomeInteger);
2: CellText := BoolToStr(SomeBoolean);
end;
end;

LeaveCriticalSection(FCriticalSection);
end;

// I'm afraid the concurrent field reading may happen only here with the private VT fields
// FNodeDataSize, FRoot and FTotalInternalDataSize, since I have Node.Data locked by the
// critical sections in the VT events, some of those may be accessed when VT is refreshed
// somehow

function TBaseVirtualTree.GetNodeData(Node: PVirtualNode): Pointer;
begin
Assert(FNodeDataSize > 0, 'NodeDataSize not initialized.');

if (FNodeDataSize <= 0) or (Node = nil) or (Node = FRoot) then
Result := nil
else
Result := PByte(@Node.Data) + FTotalInternalDataSize;
end;

更新

我已经在代码中添加了关键部分,从 TMyCreatedThread 类调用 GetNodeData 真的不安全吗,即使这个函数只返回指向记录的指针?

非常感谢

问候

最佳答案

不,尤其是你的做法。

VST 是一个视觉控件。 MainForm 也是如此,您直接从线程中引用它。 GUI 控件不是线程安全的,不应直接从线程访问。此外,您还引用了线程中的全局变量“MainForm”。这绝对不是线程安全的。

如果您需要从主窗体和单独的线程访问 VST 的数据,请勿将其直接存储在 VST.Node.Data 中。将其保存在一个外部列表中,您可以用关键部分或其他一些线程安全方法包围该列表,并在线程中访问该外部列表(首先锁定它)或在 VST 事件中访问主窗体。请参阅 Delphi RTL 中的 TLockList 以获取可锁定列表的示例,并参阅 TMultipleReadExclusiveWrite 以获取示例同步类。

关于multithreading - 从其他线程访问 VT 数据是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5586257/

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