我需要使用powershell创建两个计划任务,每个任务将运行一个powershell脚本。
应该在每天的08:00触发一次,然后每两个小时运行一次。因此,在10:00,12:00、14:00等。 另一个每天9点运行,每两个小时运行一次。所以在11:00,13:00、15:00等。
如果用户未登录,则登录后仍应立即触发任务。 可以说他登录9:35将触发这两个任务。它们如何不能同时运行?
我尝试为其中之一添加延迟,但是延迟可能为0
解决方案可以是:
$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
答案 0 :(得分:2)
问题与mutual exclusion有关,这是一个经过充分研究的问题。
一个简单的解决方案基于共享资源。任务启动时,它将尝试获取资源的互斥锁。如果这不可能,任务将等待并再次尝试直到授予超时或锁定。锁保持任务完成工作后,将在清理过程中释放锁。
简单的解决方案不能保证公平的调度,因此,如果需要公平性,请查找更多实现。
至于评论:不要依赖pid。在Windows中,可以重复使用进程ID。
为了进行快速演示,让我们像这样使用标记文件
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,请查看earlier an answer。它用于C#,但也可以针对Powershell进行调整。