Как создать 2 запланированные задачи, которые выполняются с разницей в один час, но никогда не пересекаются? - PullRequest
0 голосов
/ 31 января 2019

Мне нужно создать две запланированные задачи с помощью PowerShell, каждый из которых будет запускать сценарий PowerShell.

Каждый должен запускаться в 08:00 каждый день и запускаться каждые два часа.Итак, в 10:00, 12: 00, 14:00 и т. Д. Другой в 9 каждый день и работает каждые два часа.Таким образом, в 11:00, 13: 00, 15:00 и т. Д.

Если пользователь не вошел в систему, задачи все равно должны запускаться, как только он входит в систему. Допустим, он входит в систему 9:35это вызовет обе задачи.Как они могут не бежать одновременно?

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

Решение может быть:

  1. Когда они запускаются одновременно, онипроверьте, так ли это как-то, и один из выходов.Или
  2. Какой-то другой метод обеспечения того, чтобы они не перехватывали
   $taskAction1 = New-ScheduledTaskAction -Execute 'Powershell.exe' -argument "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $script1"
   $taskAction2 = New-ScheduledTaskAction -Execute 'Powershell.exe' -argument "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $script2"

   $taskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -Hidden -DontStopIfGoingOnBatteries

   $taskTrigger = New-ScheduledTaskTrigger -AtLogOn
   $taskTriggerWithDelay = New-ScheduledTaskTrigger -AtLogOn -RandomDelay 00:15:00

   Register-ScheduledTask -User System -Action $taskAction1 -Trigger $TasKTrigger -TaskName "Task1" -RunLevel Highest -Settings $TaskSettings -f | Out-Null
   Register-ScheduledTask -User System -Action $taskAction2 -Trigger $taskTriggerWithDelay -TaskName "Task2" -RunLevel Highest -Settings $TaskSettings -f | Out-Null

   $trigger= Get-ScheduledTask -TaskName Task1
   $trigger.Triggers.repetition.Interval = "PT2H"
   $trigger.Triggers.repetition.duration = ""
   $trigger | Set-ScheduledTask | Out-Null

   $trigger= Get-ScheduledTask -TaskName Task2
   $trigger.Triggers.repetition.Interval = "PT2H"
   $trigger.Triggers.repetition.duration = ""
   $trigger | Set-ScheduledTask | Out-Null

1 Ответ

0 голосов
/ 31 января 2019

Проблема о взаимном исключении , хорошо изученной проблеме.

Простое решение основано на общем ресурсе.Когда задача запускается, она пытается получить монопольную блокировку ресурса.Если это невозможно, задача ждет и пытается снова, пока тайм-аут или блокировка не будет предоставлена.Когда задача удержания блокировки завершит свою работу, она снимет блокировку как часть очистки.

Простое решение не гарантирует честного планирования, поэтому ищите больше реализаций, если нужна справедливость.

Что касается комментария: не полагайтесь на 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...