TParallel.For:将值存储在 TList 中,同时在 TParallel.For 循环中计算它们
TParallel.For: Store values in a TList while they are calculated in a TParallel.For loop
我想用一个TParallel.&For
循环来计算,例如,1到100000之间的质数,并将所有这些质数保存在AList: TList<Integer>
:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
AList: TList<Integer>;
LoopResult: Tparallel.TLoopResult;
begin
AList:=TList<Integer>.Create;
TParallel.&For(1, 100000,
procedure(AIndex: Integer)
begin
if IsPrime(AIndex) then
begin
//add the prime number to AList
end;
end);
//show the list
for i := 0 to AList.Count-1 do
begin
Memo1.Lines.Add(IntToStr(AList[i]));
end;
end;
可以毫无问题地并行执行计算,但 TList
是共享资源。如何以线程安全的方式将已确认的素数添加到列表中?
您只需调用 AList.Add(AIndex)
,然后在循环结束后调用 Sort()
列表。但是 TList
不是线程安全的,因此您需要在 Add()
周围加一个锁,例如 TCriticalSection
或 TMutex
:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
AList: TList<Integer>;
ALock: TCriticalSection;
LoopResult: TParallel.TLoopResult;
begin
AList := TList<Integer>.Create;
ALock := TCriticalSection.Create;
TParallel.&For(1, 100000,
procedure(AIndex: Integer)
begin
if IsPrime(AIndex) then
begin
ALock.Enter;
try
AList.Add(AIndex);
finally
ALock.Leave;
end;
end;
end);
AList.Sort;
for i := 0 to AList.Count-1 do
begin
Memo1.Lines.Add(IntToStr(AList[i]));
end;
ALock.Free;
AList.Free;
end;
或使用TThreadList<T>
代替:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
AList: TThreadList<Integer>;
LList: TList<Integer>;
LoopResult: TParallel.TLoopResult;
begin
AList := TThreadList<Integer>.Create;
TParallel.&For(1, 100000,
procedure(AIndex: Integer)
begin
if IsPrime(AIndex) then
begin
AList.Add(AIndex);
end;
end);
LList := AList.LockList;
try
LList.Sort;
for i := 0 to LList.Count-1 do
begin
Memo1.Lines.Add(IntToStr(LList[i]));
end;
finally
AList.UnlockList;
end;
AList.Free;
end;
我想用一个TParallel.&For
循环来计算,例如,1到100000之间的质数,并将所有这些质数保存在AList: TList<Integer>
:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
AList: TList<Integer>;
LoopResult: Tparallel.TLoopResult;
begin
AList:=TList<Integer>.Create;
TParallel.&For(1, 100000,
procedure(AIndex: Integer)
begin
if IsPrime(AIndex) then
begin
//add the prime number to AList
end;
end);
//show the list
for i := 0 to AList.Count-1 do
begin
Memo1.Lines.Add(IntToStr(AList[i]));
end;
end;
可以毫无问题地并行执行计算,但 TList
是共享资源。如何以线程安全的方式将已确认的素数添加到列表中?
您只需调用 AList.Add(AIndex)
,然后在循环结束后调用 Sort()
列表。但是 TList
不是线程安全的,因此您需要在 Add()
周围加一个锁,例如 TCriticalSection
或 TMutex
:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
AList: TList<Integer>;
ALock: TCriticalSection;
LoopResult: TParallel.TLoopResult;
begin
AList := TList<Integer>.Create;
ALock := TCriticalSection.Create;
TParallel.&For(1, 100000,
procedure(AIndex: Integer)
begin
if IsPrime(AIndex) then
begin
ALock.Enter;
try
AList.Add(AIndex);
finally
ALock.Leave;
end;
end;
end);
AList.Sort;
for i := 0 to AList.Count-1 do
begin
Memo1.Lines.Add(IntToStr(AList[i]));
end;
ALock.Free;
AList.Free;
end;
或使用TThreadList<T>
代替:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
AList: TThreadList<Integer>;
LList: TList<Integer>;
LoopResult: TParallel.TLoopResult;
begin
AList := TThreadList<Integer>.Create;
TParallel.&For(1, 100000,
procedure(AIndex: Integer)
begin
if IsPrime(AIndex) then
begin
AList.Add(AIndex);
end;
end);
LList := AList.LockList;
try
LList.Sort;
for i := 0 to LList.Count-1 do
begin
Memo1.Lines.Add(IntToStr(LList[i]));
end;
finally
AList.UnlockList;
end;
AList.Free;
end;