Mein Gedanke ist, eine Warteschlange einzurichten, indem für jede neue Instanz Ihres Skripts eine Sperrdatei erstellt wird. Bei der Ausführung des Skripts wird ein Verzeichnis geprüft, in dem die Warteschlange nach vorhandenen Instanzen des Skripts gesucht wird. Wenn keine vorhanden ist, fügt sich das Skript vor der Warteschlange ein, führt eine Aktion aus (führt den Code aus) und bereinigt dann die Sperre. Wenn es Sperren gibt, wird am Ende der Warteschlange eine neue hinzugefügt, und die Instanz prüft endlos, bis sie sich am Anfang der Warteschlange befindet.
Auf diese Weise können Sie dasselbe Skript mehrmals ausführen, wobei alle einzeln durch Prüfen der extern verfügbaren Warteschlange selbst behandelt werden.
Die Sperrdateien sind als Index, Trennzeichen ("_") und Prozess-ID strukturiert.
Clear-Host function New-Lock ([int] $index) { $newLock = "$index" + "_" + $pid + ".lck" New-Item $queue$newLock | Out-Null } $queue = "C:\locks\" # find the end of the stack $locks = gci $queue *.lck | sort | select -expandproperty name # if locks exist, find the end of the stack by selecting the index of the last lock if($locks) { # gets the last lock file, selects the index by splitting on the delimiter [int]$last = [convert]::ToInt32(($locks | select -last 1).Split("_")[0],10) # add the lock to the end of the stack New-Lock ($last + 1) } # if no locks exist, create one at the top of the stack else { New-Lock 0 } # check if we're at the top of the stack do { $locks = gci $queue *.lck | sort | select -expandproperty name # this is the PID on the top of the stack [int]$top = [convert]::ToInt32(($locks | select -first 1).Split("_")[1].Split(".")[0],10) write-verbose "not at the top..." sleep 1 } until ($pid -eq $top) # if we're here, we've been to the top. it's our turn to do something Write-Verbose "we've reached the top!" # <do something. put your code here> # might be good to add some Start-Sleep here # </do something put your code here> # now that we're done, let's delete our lock gci $queue | select -first 1 | Remove-Item
Nachfolgend finden Sie ein Beispiel für eine fiktive Zeitleiste, in dem Sie drei Dateien heruntergeladen haben (ich habe zufällige PIDs ausgewählt).
- Datei 1 wird heruntergeladen und startet das Skript. Es sind keine Sperren vorhanden. Sperre "0_19831" erstellen. Wir sind an der Spitze des Stapels, also wird Ihr Code ausgeführt. Dies ist ein großes E-Book, daher dauert die Ausführung Ihres Dateiübertragungscodes eine volle Minute.
- Datei 2 wird heruntergeladen und startet das Skript. Sperre (n) existieren Sperre "1_332" erstellen. Wir sind nicht an der Spitze des Stapels, also warten wir in unserem
do/until
und warten weiter, bis wir an erster Stelle stehen. - Datei 1 ist fertig kopiert. Lösche die Sperre "0_19831".
- Datei 3 wird heruntergeladen und startet das Skript. Sperre (n) existieren Sperren "2_7582" erstellen. Wir sind nicht an der Spitze des Stapels, warten Sie, bis wir es sind.
- Datei 2 ist fertig kopiert. Lösche die Sperre "1_332".
- Datei 3 ist fertig kopiert. Lösche die Sperre "2_7582".
Diese Lösung ist nicht kugelsicher, kann jedoch je nach Skalierung funktionieren.