【发布时间】:2012-10-10 11:36:42
【问题描述】:
我有一个 Win32 线程(没有 TThread),它一直在运行并遍历一个静态数组。主线程可以修改数组的字段。 没有像 TThreadList 之类的组件(对于无 vcl 应用程序),只使用 Windows 关键部分 (TRTLCriticalSection) 的最佳方法是什么?
代码:
type
T = record
Idx: Integer;
Str: string;
Num: Real;
Enabled: Boolean;
end;
var
A: Array[0..9] of T;
Cnt: Integer;
CS: TRTLCriticalSection;
procedure thread;
var
I: Integer;
begin
while True do
begin
for I := Low(A) to High(A) do
begin
if A[I].Enabled then
begin
//modify some fields from A[I]
Inc(A[I].Idx);
if A[I].Idx >= 10 then
begin
A[I].Enabled := False;
InterlockedDecrement(Cnt);
end;
end;
end;
if Cnt = 0 then Sleep(1);
end;
end;
procedure Add(...); //called only from mainthread
function GetFreeField: Integer;
begin
for Result := Low(A) to High(A) do
if not A[Result].Enabled then Exit;
Result := -1;
end;
var
I: Integer;
begin
I := GetFreeField;
if I = -1 then Exit;
//set fields A[I]
A[I].Enabled := True;
InterlockedIncrement(Cnt);
end;
一开始,数组被初始化为 enabled = false 和 cnt = 0。
下面的修改够吗?
procedure thread;
var
I: Integer;
begin
while True do
begin
for I := Low(A) to High(A) do
begin
EnterCriticalSection(CS);
if A[I].Enabled then
begin
LeaveCriticalSection(CS);
//modify some fields from A[I]
Inc(A[I].Idx);
if A[I].Idx >= 10 then
begin
EnterCriticalSection(CS);
A[I].Enabled := False;
LeaveCriticalSection(CS);
InterlockedDecrement(Cnt);
end;
end
else
LeaveCriticalSection(CS);
end;
if Cnt = 0 then Sleep(1);
end;
end;
procedure Add(...); //called only from mainthread
var
I: Integer;
begin
I := GetFreeField;
if I = -1 then Exit;
//set fields A[I]
EnterCriticalSection(CS);
A[I].Enabled := True;
LeaveCriticalSection(CS);
InterlockedIncrement(Cnt);
end;
【问题讨论】:
-
TThreadList不是VCL的一部分,它在 System.Classes 中。在这样的列表中添加/删除项目是线程安全的。不过,操作列表项必须受到保护。
标签: multithreading delphi critical-section static-array