在TParallel.For中使用SetCurrentDir和WinExec32AndWait跳过一些迭代

时间:2016-07-09 06:47:00

标签: delphi delphi-xe7

我在Tparallel.for中遇到了迭代次数的问题。 我有100个文件夹,每个文件夹中都存在一个要运行的文件(run.bat)。 运行后,在文件夹中创建out.txt文件。当我使用Tparalle.for进行100次迭代时,我会随机收到90到98 out.txt,而它是100。 我的代码如下(Delphi XE7):

TParallel.For(1, 100, procedure(i: integer)
    begin
      SetCurrentDir(path + '\test\' + IntToStr(i));
      WinExec32AndWait(PChar('run.bat'), 0);
    end);

2 个答案:

答案 0 :(得分:3)

流程工作目录是流程的单个值。您希望每个任务都有自己的私有副本,但这根本不是工作目录的运行方式。在更多技术术语中,共享流程范围的工作目录上存在数据竞争。由于这种竞争在创建子进程时它们继承了父进程的工作目录,但由于竞争,一些子进程继承了针对不同子进程的工作目录。这是并行编程带来的经典错误之一。

通过避免使用父进程工作目录来解决这个问题。根本不要修改它。而是在创建工作目录时将工作目录传递给每个子进程。这可以使用CreateProcessShellExecuteEx完成。您的WinExec32AndWait函数可能需要修改才能接受工作目录参数。

这可以确保为每个不同的子进程创建工作目录的单独副本,从而解决了这个问题。

答案 1 :(得分:0)

setcurrentdir当然不是多线程的!如果2个线程同时将当前目录设置为xxx怎么办? :)

改为

Tparallel.for(1,100.procedure(i:integer)
begin
  winexec32andwait(pchar(path+'\test\'+inttostr(i) + '\run.bat'),0);
end);