Проблема о взаимном исключении , хорошо изученной проблеме.
Простое решение основано на общем ресурсе.Когда задача запускается, она пытается получить монопольную блокировку ресурса.Если это невозможно, задача ждет и пытается снова, пока тайм-аут или блокировка не будет предоставлена.Когда задача удержания блокировки завершит свою работу, она снимет блокировку как часть очистки.
Простое решение не гарантирует честного планирования, поэтому ищите больше реализаций, если нужна справедливость.
Что касается комментария: не полагайтесь на pid.В Windows идентификаторы процессов можно использовать повторно.
Для быстрой демонстрации давайте воспользуемся файлом флага, например так:
function getlock() {
$file = $null
while($file -eq $null) {
try { $file = [System.IO.File]::Open("c:\temp\flag.txt", "open", "read", "none") } catch {
write-host "waiting..."
start-sleep -seconds 2
}
}
write-host "got lock!"
start-sleep -seconds 5
$file.close()
}
Попробуйте его, загрузив функцию в два сеанса Powershell и вызвав ее.их в течение нескольких секунд.Увеличьте 5-секундный сон, если у вас возникли проблемы с переключением задач.Каждая функция попытается получить эксклюзивную блокировку файла флага.Если это невозможно, будет выдано исключение.Процесс, который запаздывает в игре, будет спать в течение двух секунд и будет повторяться, пока первый не снимет блокировку.См. File.Open()
для получения более подробной информации о режимах общего доступа к файлам.
У файлов флагов есть проблемы, поэтому для более надежного IPC посмотрите на ранее ответ .Это для C #, но может быть настроено и для Powershell.