Запуск нескольких параллельных фоновых процессов, а затем ожидание завершения всех из них в Windows

22448
Sergio

Кто-нибудь знает, есть ли cmd-скрипт, который делает это и / или инструмент командной строки, готовый к работе?

11
Это может повредить ваши данные! Santosh Kumar 12 лет назад 0
@Santosh: что вы подразумеваете под «может повредить ваши данные»? В моем конкретном случае фоновые задачи будут обрабатывать свои собственные независимые наборы данных. Нет риска одновременных изменений. Sergio 12 лет назад 8
Со стороны Win32 API я * думаю, что * [WaitForMultipleObjects] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687028%28v=vs.85%29.aspx) с bWaitAll = TRUE будет сделать работу. Нетрудно написать программу, которая просто отбирает программы, заданные в некотором входном файле, если нет удовлетворительных ответов. grawity 12 лет назад 0
@ grawity: да, я планирую сделать это, если ничего не появится (и опубликую код здесь), но давайте посмотрим, смогу ли я избежать изобретать велосипед :) Sergio 12 лет назад 1
Изобретать колесо - это хорошо, если существующие колеса имеют квадратную форму ... grawity 12 лет назад 0

5 ответов на вопрос

5
RobW

Создайте три пакетных файла ниже. Main.bat запускает 1.bat и 2.bat

1.bat и 2.bat записывают временные файлы, которые проверяет main.bat. Пока работают 1.bat и 2.bat, main.bat сообщает, что обработка все еще происходит. Когда вы нажимаете ввод в открытом окне 1.bat или 2.bat, временный файл удаляется, и программа завершает работу. Это имитирует остановку обработки для этого файла .bat. Если вы сделаете это для 1 и 2.bat, main.bat сообщит вам, что обработка для этих процессов завершена. Вы можете заставить 1.bat и 2.bat делать все, что захотите, если вы очистите временный файл, когда закончите. На этом этапе main.bat также может делать все, что вы хотите.

1.bat

echo %time% > 1.tmp pause del 1.tmp exit  

2.bat

echo %time% > 2.tmp pause del 2.tmp exit 

main.bat

@echo off start "1" 1.bat start "2" 2.bat @ping -n 1 127.0.0.1 > nul :loop @echo Processing...... if not exist *.tmp goto :next @ping -n 5 127.0.0.1 > nul goto loop :next @echo Done Processing! 
Сделав это раньше, я могу сказать вам, что этот подход не так сложен, как кажется. Кроме того, его легко обслуживать - расширять и добавлять логику, а также легко обучать кого-то другому его обслуживать. Обычно эти вещи обретают собственную жизнь ... RobW 12 лет назад 0
Я доволен этим решением. user1068446 11 лет назад 0
1
Tom Wijsman

Единственный способ сделать это - запустить отдельные пакетные файлы (см. start /?), Которые запускают отдельную задачу, и написать текстовый файл после завершения. Затем вы периодически проверяете, были ли созданы текстовые файлы.

0
uSlackr

Вы можете посмотреть командлет Powershell Start-Job. Это должно позволить вам сделать это. Подробнее здесь Powershell - это предпочтительная оболочка Microsoft. Это намного мощнее, чем сценарии cmd и хорошо тратит ваше время

Это не ждет их всех, чтобы прекратить? Tom Wijsman 12 лет назад 0
Это, конечно, может в зависимости от того, как вы это пишете. Вы можете опросить запущенные задания, чтобы увидеть, завершены ли они, и выйти из вашего скрипта, как только они это сделали. Код на этой странице обрабатывает целый список заданий, три за один раз, и ожидает их выхода. uSlackr 12 лет назад 0
Хм, никогда не делал ничего раньше с Powershell. Я попытался изменить пример, чтобы запустить произвольные процессы и дождаться их завершения, и примерно через 30 минут и 100 поисков по M $ technet я сдался. Мне жаль, если я кого-то обидел, но Powershell - это дерьмо. Это легче сделать в C (что, я думаю, говорит ...) В любом случае, бьюсь об заклад, кто-то найдет это полезным. Sergio 12 лет назад 0
Если есть одна вещь, которой не является Powershell, это дерьмо, и ты не обидишь мои чувства, если не будешь этим пользоваться. Вы, однако, не научитесь этому за 30 минут поиска. uSlackr 12 лет назад 0
PowerShell - это не дерьмо, а полноценный язык программирования, а не традиционный sh-подобный синтаксис. Я помню точно так же, как Perl, Python, Tcl, C # и любой другой язык, который я пытался выучить «для лулза», но без реального использования. (Когда я действительно * нуждался в них *, все прошло довольно легко.) grawity 12 лет назад 1
0
Harry Johnston

Достаточно просто, при условии, что процессы не требуют стандартного ввода или вывода. Из командной строки или в командном файле:

process1 | process2 | process3 | process4 

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

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

Хм, что я получаю, так это то, что все процессы действительно запускаются одновременно, но process3 продолжает ждать, пока process4 завершится, process2 продолжает ждать, пока process3 завершится, и так далее. Кстати, из классической командной строки Windows. Sergio 12 лет назад 0
@Sergio: Что вы подразумеваете под "продолжал ждать"? Harry Johnston 12 лет назад 0
0
OlivierR

Or you can use this: http://www.out-web.net/?p=167

I did it, it works, however it happens sometimes that the PID of the finished process is immediately re-used by another Windows processus which just started, and it makes the detection of the end of your processus hazardous/erroneous.

Пожалуйста, суммируйте, что говорит эта ссылка. Если страница закрывается, этот ответ не поможет. Kevin Panko 10 лет назад 1