2016-08-12 1 views
1

Ich habe ein generischen Fenster bauen Batch (d build.bat), die in parrallel mit unterschiedlichen Parametern ausgeführt wird.in Windows-Batch-Datei

start build.bat device1 
start build.bat device2 
start build.bat device3 

Aber in diesem Stapel gibt es eine ausführbare Datei, die abstürzt, wenn es parallel aufgerufen wird.

Ist es möglich, mit Fenstern build-in Funktionen, diesen Aufruf zu blockieren, wenn es bereits in einer anderen Charge ausgeführt wird und fortgesetzt werden, wenn es in diesem anderen Charge beendet hat?

ist der Inhalt dieser Partie sagen Lassen

start delay 5 

ist, wenn die Partie muss die Verzögerung mehrere Male dann aufgerufen wird, nicht ausgeführt werden, wenn eine andere Verzögerung derzeit ausgeführt wird.

Dies ist vergleichbar mit Semaphoren.

So ist das Ziel, so etwas wie dieser

CheckAndWaitIfDelayIsRunning 
start delay 5 

Vielen Dank im Voraus zu haben.

+0

@AdrianoRepetti: Der 'Starten' Befehl hat keine Option, die für die Beendigung warten einen weiteren Prozess _of _... – Aacini

+0

@Aacini wahr, ich wieder lesen Sie einfach die Frage und Ich habe den Hauptpunkt verpasst (warte auf einen anderen Prozess, nicht auf den zweiten Batch selbst) –

Antwort

6

Sie Semaphore im Batch unter Verwendung eines lock by file aufbauen können.

:lock 
2>nul (
    > sema1.lock (
    delay 5 
    REM The next line is for proper finishing the lock block 
    (call) 
) 
) || goto :lock 

Der Trick ist, dass das Schreiben an sema1.lock nur für einen Prozess zum Zeitpunkt erlaubt.
Jeder anderer Prozess fehlschlagen und den inneren Block überspringt, wird die || goto :lock wiederholen, bis es möglich ist, auf die sema1.lock Datei zu schreiben.
Ein Nachteil dieser Technik ist die verzehr der CPU, da diese Semaphore nicht wirklich warten, es ist eher ein Polling Semaphore.

mehr für SO:How do you have shared log files under Windows?

+0

Wie wäre es mit einem 'Timeout 1'-Befehl, um die Abfragerate zu reduzieren? Funktioniert das? – aschipfl

+1

Ja, das funktioniert, kann aber die Programmreaktion verlangsamen, da semaLock im Durchschnitt 0,5 Sekunden wartet, wenn auf eine Freigabe von einem anderen Thread gewartet wird – jeb

1

sehen Laut der Antwort optimiert ich zwei Dinge:

  • Console Ausgabe noch sichtbar ist und nicht in eine Datei umgeleitet
  • % Errorlevel% der Fehler von meiner Aufgabe enthält

Es verwendet einen Ordner als Sperre, die das erste Mal erstellt wird.
Ping wird als Wartezeit verwendet und auf 1000 ms gesetzt.
Es zählt die Anzahl der Zyklen, die der Thread wartet, bis er die Berechtigung zur Ausführung seiner Aufgabe erhält.

Script

set lockMyName="%TEMP%\my.lock"  
set lockMyCounterMs=0 
set lockMyTimeMs=1000 
@echo [ INFO ] Getting my lock... 
:lock_my 
md %lockMyName% 2>nul 
if "%errorlevel%" neq "0" (
    set /a lockMyCounterMs+=%lockMyTimeMs% 
    :: commonly used timeout without waiting for input (must be invalid ip address) 
    ping 1.0.0.0 -n 1 -w %lockMyTimeMs% >nul 
    goto :lock_my 
) 
@echo [ INFO ] ... locked ^(waited %lockMyCounterMs% ms for lock^) 

::do your task here 

@echo [ INFO ] ...release my lock 
rd /Q %lockMyName% 2>nul