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

14

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

Sergio
источник
Это может повредить ваши данные!
Сантош Кумар
8
@Santosh: что вы подразумеваете под «может повредить ваши данные»? В моем конкретном случае фоновые задачи будут обрабатывать свои собственные независимые наборы данных. Нет риска одновременных изменений.
Серхио
1
Со стороны Win32 API, я думаю , что WaitForMultipleObjects с bWaitAll = TRUE сделает эту работу. Нетрудно написать программу, которая просто разветвляет программы, заданные во входном файле, если нет удовлетворительных ответов.
user1686
1
@ grawity: да, я планирую сделать это, если ничего не появится (и опубликую код здесь), но давайте посмотрим, смогу ли я избежать повторного изобретения колеса :)
Sergio
Изобретать колесо - это хорошо, если существующие колеса имеют квадратную
форму

Ответы:

10

Создайте три пакетных файла ниже. 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
источник
Сделав это раньше, я могу сказать вам, что этот подход не так сложен, как кажется. Кроме того, его легко обслуживать - расширять и добавлять логику, а также легко обучать кого-то другому его обслуживать. Обычно эти вещи
обретают
Я доволен этим решением.
user1068446
Не могли бы вы расширить команду @ping? Я не понимаю, почему вы решили сделать это и что такое 127.0.0.1.
Джо
6

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

process1 | process2 | process3 | process4

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

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

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

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

Тамара Вийсман
источник
0

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

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

Или вы можете использовать это: http://www.out-web.net/?p=167

Я сделал это, это работает, однако иногда случается, что PID завершенного процесса немедленно повторно используется другим процессором Windows, который только что запустился, и это делает обнаружение конца вашего процесса опасным / ошибочным.

OlivierR
источник
2
Пожалуйста, суммируйте, что говорит эта ссылка. Если страница закрывается, этот ответ не поможет.
Кевин Панко
Кажется, слишком поздно.
Роберт Масса
0

Я тоже искал похожую задачу. Цель состояла в том, чтобы запустить несколько команд параллельно и извлечь вывод (stdout & error) всех параллельных процессов. Затем дождитесь завершения всех параллельных процессов и выполните другую команду. Ниже приведен пример кода для файла BAT, который может быть выполнен в CMD:

( start "" /B cmd /c ping localhost -n 6 ^>nul timeout /t 5 /nobreak start "" /B /D "C:\users\username\Desktop" cmd /c dir ^> dr.txt ^2^>^&^1 start "" /B cmd /c ping localhost -n 11 ^>nul timeout /t 10 /nobreak ) | pause Echo waited timeout /t 12 /nobreak

()Сначала выполняются все операторы внутри , ждите их завершения, затем выполняются две последние строки. Все команды, начинающиеся с start, выполняются одновременно.

Эти ссылки полезны: /programming//a/43762349/9689416 и https://ss64.com/nt/start.html.

Вивек
источник