Executando vários processos simultâneos em segundo plano, aguarde o término de todos eles no Windows

14

Alguém sabe se existe um script cmd que faz isso e / ou uma ferramenta de linha de comando pronta para o trabalho?

Sergio
fonte
Fazer isso pode prejudicar seus dados!
27412 Santosh Kumar
8
@ Santosh: o que você quer dizer com "pode ​​prejudicar seus dados"? No meu caso específico, as tarefas em segundo plano processariam seus próprios conjuntos de dados independentes. Sem riscos de modificações simultâneas.
26312 Sergio Sergio
1
Do lado da API do Win32, acho que WaitForMultipleObjects com bWaitAll = TRUE faria o trabalho. Não seria difícil escrever um programa que apenas execute programas fornecidos em algum arquivo de entrada, se não houver respostas satisfatórias.
user1686
1
@grawity: sim, eu planejo fazer apenas que, se nada vem à tona (e postar o código aqui), mas vamos ver se eu posso evitar reinventar a roda :)
Sergio
Reinventar a roda é uma coisa boa se as rodas existentes atualmente são quadrados ...
user1686

Respostas:

10

Crie os três arquivos em lotes abaixo. Main.bat lança 1.bat e 2.bat

1.bat e 2.bat gravam arquivos temporários para os quais o main.bat verifica. Enquanto o 1.bat e o 2.bat estão funcionando, o main.bat informa que o processamento ainda está ocorrendo. Quando você pressiona enter na janela aberta 1.bat ou 2.bat, o arquivo temporário é excluído e o programa é encerrado. Isso simula a parada do processamento para esse arquivo .bat. Se você fizer isso para 1 e 2.bat, o main.bat informará que o processamento foi concluído para esses processos. Você pode fazer com que 1.bat e 2.bat façam o que quiser, desde que limpe o arquivo temporário quando terminar. Nesse ponto, o main.bat também pode fazer o que você quiser.

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
fonte
Tendo feito isso antes, posso dizer que essa abordagem não é tão difícil quanto parece. Além disso, é fácil de manter - para expandir e adicionar lógica, e fácil de treinar alguém para mantê-lo. Normalmente, estas coisas assumem vida própria ...
RobW
Estou feliz com esta solução.
user1068446
6

Simples o suficiente, desde que os processos não precisem de entrada ou saída padrão. Na linha de comando ou em um arquivo em lotes:

process1 | process2 | process3 | process4

Isso executará todos os quatro processos simultaneamente e não retornará até que todos tenham saído. (Possível exceção: se um processo fechar explicitamente a saída padrão, ele poderá ser tratado como se tivesse saído. Mas isso é incomum, muito poucos processos fazem isso.)

Não sei exatamente quantos processos você pode iniciar simultaneamente dessa maneira. Eu tentei até dez.

Harry Johnston
fonte
Uhm, o que eu entendo é que todos os processos são realmente iniciados ao mesmo tempo, mas process3 é mantido aguardando até que o processo4 seja concluído, process2 é mantido aguardando até que o processo3 seja concluído e assim por diante. A propósito, isso é do prompt de comando clássico do Windows.
Sergio
@Sergio: O que você quer dizer com "continuou esperando"?
Harry Johnston,
1

A única maneira de fazer isso é iniciar arquivos em lote separados (consulte start /?) que executam a tarefa individual e gravam um arquivo de texto após a conclusão. Em seguida, você verifica periodicamente se os arquivos de texto foram criados.

Tamara Wijsman
fonte
0

Você pode olhar para o cmdlet Powershell Start-Job. Deve permitir que você faça isso. Mais aqui O Powershell é o shell preferido da Microsoft. É muito mais poderoso que os scripts cmd e bem o investimento do seu tempo

uSlackr
fonte
Isso não espera que todos eles terminem?
Tamara Wijsman
Certamente pode, dependendo de como você o escreve. Você pode pesquisar os trabalhos iniciados para verificar se eles foram concluídos e sair do seu script depois de concluídos. O código nessa página processa uma lista completa de trabalhos, três por vez, e aguarda a saída deles.
uSlackr
Uhm, nunca fiz nada antes com o Powershell. Tentei mudar o exemplo para executar processos arbitrários e esperar que eles fossem concluídos. Após cerca de 30 minutos e 100 pesquisas no M $ technet, desisti. Me desculpe se magoei os sentimentos de alguém, mas o Powershell é uma porcaria. É mais fácil fazer isso em C (o que eu acho que está dizendo ...) Obrigado de qualquer maneira, aposto que alguém ainda achará isso útil.
27312 Sergio
Se há uma coisa que Powershell não é é uma porcaria e você não vai machucar meus sentimentos se não a usar. Você não aprenderá em 30 minutos de pesquisa.
uSlackr
1
O PowerShell não é uma porcaria, é apenas uma linguagem de programação completa que você precisa aprender, em vez de uma sintaxe tradicional do tipo sh. Lembro-me de me sentir exatamente da mesma maneira sobre Perl, Python, Tcl, C # e todas as outras linguagens que tentei aprender "para o lulz" sem qualquer uso real ainda. (Quando eu realmente precisava deles, porém, ele foi bastante facilidade.)
user1686
0

Ou você pode usar isso: http://www.out-web.net/?p=167

Eu fiz isso, funciona, no entanto, às vezes acontece que o PID do processo finalizado é reutilizado imediatamente por outro processo do Windows que acabou de iniciar e torna a detecção do final do seu processo arriscada / incorreta.

OlivierR
fonte
2
Resuma o que esse link diz. Se a página cair, esta resposta não será útil.
precisa saber é o seguinte
Tarde demais é parece.
Robert Massa
0

Eu também estava procurando uma tarefa semelhante. O objetivo era executar vários comandos em paralelo e extrair a saída (stdout e erro) de todos os processos paralelos. Aguarde todos os processos paralelos concluírem e executem outro comando. A seguir está um código de amostra para o arquivo BAT, que pode ser executado no 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

Todas as instruções internas ()são executadas primeiro, aguarde a conclusão e as duas últimas linhas são executadas. Todos os comandos iniciados com startsão executados simultaneamente.

Esses links são úteis: /programming//a/43762349/9689416 e https://ss64.com/nt/start.html

Vivek
fonte