TParallel.For:在TParallel.For循环中计算值时将值存储在TList中 [英] TParallel.For: Store values in a TList while they are calculated in a TParallel.For loop

查看:266
本文介绍了TParallel.For:在TParallel.For循环中计算值时将值存储在TList中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用TParallel.&For循环来计算例如1到100000之间的质数,并将所有这些质数保存在AList: TList<Integer>中:

I want to use a TParallel.&For loop to calculate, for example, the prime numbers between 1 and 100000 and save all these prime numbers in 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是共享资源.如何以线程安全的方式将已确认的素数添加到列表中?

The calculations can be performed in parallel without issue but the TList is a shared resource. How can I add confirmed primes to the list in a threadsafe way?

推荐答案

您只需调用AList.Add(AIndex),然后在循环结束后调用Sort()列表即可.但是TList不是线程安全的,因此您需要在Add()周围加锁,例如TCriticalSectionTMutex:

You would simply call AList.Add(AIndex), and then Sort() the list after the loop is finished. But TList is not thread-safe, so you need a lock around the Add(), like a TCriticalSection or 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:在TParallel.For循环中计算值时将值存储在TList中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆