2016-07-09 3 views
-3

У меня проблема с количеством итераций в Tparallel.for. У меня есть 100 папка и в каждой папке есть файл для запуска (run.bat). После запуска файл out.txt создается в папке. Когда я использую Tparalle.for со 100 итерациями, я получаю случайным образом от 90 до 98 out.txt, пока он равен 100. мой код выглядит следующим образом (Delphi XE7):Использование SetCurrentDir и WinExec32AndWait в TParallel.For пропускает некоторые итерации

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

Извините, но я не понимаю, в чем проблема? Что вы ожидаете и каков реальный результат? Возможно также посмотреть: http://stackoverflow.com/help/asking – Andrej

ответ

3

Рабочий процесс процесса является единственным значением для процесса. Вы ожидаете, что каждая задача будет иметь собственную личную копию, но это просто не то, как работает рабочий каталог. В более технических терминах существует расписание данных в общем рабочем каталоге общего процесса. Из-за этой расы, когда создаются дочерние процессы, они наследуют рабочий каталог родителя, но из-за расы некоторые дети наследуют рабочий каталог, предназначенный для разных детей. Это одна из классических ошибок, допущенных при параллельном программировании.

Справьтесь с этим, избегая использования рабочего каталога родительского процесса. Не изменяйте его вообще. Вместо этого передайте рабочий каталог каждому дочернему процессу при их создании. Это можно сделать довольно просто, используя CreateProcess или ShellExecuteEx. Возможно, вам необходимо изменить функцию WinExec32AndWait, чтобы принять аргумент рабочей директории.

Это решает проблему, гарантируя, что вы создадите отдельную копию рабочего каталога для каждого отдельного дочернего процесса.

+0

Функция WinExec32AndWait выглядит так: – AMIR

+0

Функция WinExec32AndWait (const Cmd: string; const CmdShow: Integer): Cardinal; var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; начало Результат: = кардинал ($ FFFFFFFF); FillChar (StartupInfo, SizeOf (TStartupInfo), # 0); – AMIR

+0

StartupInfo.cb: = SizeOf (TStartupInfo); StartupInfo.dwFlags: = STARTF_USESHOWWINDOW; // STARTF_USESHOWWINDOW // NORMAL_PRIORITY_CLASS; StartupInfo.wShowWindow: = CmdShow; – AMIR

0

setcurrentdir выключен, конечно, не многопоточно! что, если 2 потока в то же время установить текущий каталог в xxx? :)

сделать вместо

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

Возможно, нужно установить рабочий каталог в дочернем процессе –

+0

, если использовать winexec32andwait без setcurrentdir, файл run.bat не будет запущен. – AMIR

+0

@AMIR SetCurrentDir устанавливает текущий ** динамический динамик ** для текущего процесса. После этого вы начинаете процесс с партии. Вы забываете о многопоточном аспекте. task1 установить текущий каталог, task2 установить текущий каталог, task1 запускает пакет (oops, on wrong current dir) - это ваша проблема –

 Смежные вопросы

  • Нет связанных вопросов^_^