我在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);
答案 0 :(得分:3)
流程工作目录是流程的单个值。您希望每个任务都有自己的私有副本,但这根本不是工作目录的运行方式。在更多技术术语中,共享流程范围的工作目录上存在数据竞争。由于这种竞争在创建子进程时它们继承了父进程的工作目录,但由于竞争,一些子进程继承了针对不同子进程的工作目录。这是并行编程带来的经典错误之一。
通过避免使用父进程工作目录来解决这个问题。根本不要修改它。而是在创建工作目录时将工作目录传递给每个子进程。这可以使用CreateProcess
或ShellExecuteEx
完成。您的WinExec32AndWait
函数可能需要修改才能接受工作目录参数。
这可以确保为每个不同的子进程创建工作目录的单独副本,从而解决了这个问题。
答案 1 :(得分:0)
setcurrentdir当然不是多线程的!如果2个线程同时将当前目录设置为xxx怎么办? :)
改为
Tparallel.for(1,100.procedure(i:integer)
begin
winexec32andwait(pchar(path+'\test\'+inttostr(i) + '\run.bat'),0);
end);