Delphi 2007 AsyncMultiSync 不工作

Delphi 2007 AsyncMultiSync Does not work

我尝试使用 AsyncCalls 编写一个并行线程示例,下面是并行计算素数的数量

program Project3;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Math,
  Windows,
  AsyncCalls in 'AsyncCalls.pas';

const
  N = 1000000;
  MAXT = 100;

var
  threads : array of IAsyncCall;
  ans: array of integer;
  cnt: DWORD;
  i, v, j, k, portion: integer;

function IsPrime(x: integer): boolean;
var
  i: integer;
begin
  if (x <= 1) then 
  begin
    Result := False;
    Exit;
  end;
  if (x = 2) then
  begin
    Result := True;
    Exit;
  end;
  for i:= 2 to Ceil(Sqrt(x))do
  begin
    if (x mod i = 0) then
    begin
      Result := False;
      Exit;
    end;
  end;
  Result := True;
end;

procedure DoWork(left, right: integer; value: PInteger); cdecl;
var
  i, cnt: integer;
begin
  cnt := 0;
  for i := left to right do
  begin
    if (IsPrime(i)) then
    begin
      Inc(cnt);
    end;
  end;
  value^ := cnt;
end;

begin
  // Paralell
  cnt := GetTickCount;
  SetLength(ans, MAXT);
  SetLength(threads, MAXT);
  portion := N div MAXT;
  for i := 0 to MAXT - 2 do
  begin
    // left index
    j := i * portion;
    // right index
    k := (i + 1) * portion - 1;
    threads[i] := AsyncCall(@DoWork, [j, k, @ans[i]]);
  end;
  // last thread
  j := (MAXT - 1) * portion;
  threads[MAXT - 1] := AsyncCall(@DoWork, [j, N - 1, @ans[MAXT - 1]]);
  // Join, doesn't seem to wait all
  AsyncMultiSync(threads, True, INFINITE);
  // ****Adding a delay to wait for all threads*****
  // Sleep(1000);
  // Sum the answer
  v := 0;
  for i := 0 to MAXT - 1 do
  begin
    Inc(v, ans[i]);
  end;
  Writeln('Parallel = ', GetTickCount - cnt);
  Writeln('Answer = ', v);  
  // Serial
  cnt := GetTickCount;
  DoWork(0, N - 1, @v);
  Writeln('Serial = ', GetTickCount - cnt);
  Writeln('Answer = ', v);  
  Readln;
end.

奇怪的行为。 AsyncMultiSync 似乎根本没有等待。如果我不添加 Sleep(1000),输出是

Parallel = 172
Answer = 0
Serial = 453
Answer = 78498

如果我加上 Sleep(1000),输出是正确的:

Parallel = 1188
Answer = 78498
Serial = 265
Answer = 78498

我尝试使用 threads[i].Sync,它产生了相似的结果。

我是不是漏掉了什么?

环境是D2007,Windows10 64位首页

Documentation表示不要超过最大等待对象数,61。

因此您将不得不减少 MaxT 常量。