我有一个用golang编写的应用程序(部分),作为其操作的一部分,它将产生一个外部进程(用c编写)并开始监视。这个外部过程可能需要很长时间才能完成,因此我正在寻找一种方法来防止机器在处理过程中睡眠或休眠。
我希望能够放弃此锁定,以便在进程完成后允许机器进入休眠/休眠状态
我最初的目标是Windows,但跨平台解决方案是理想的(nix甚至是休眠?)。
答案 0 :(得分:1)
在Windows上,您的第一步是尝试SetThreadExecutionState
:
启用应用程序以通知系统它正在使用中,从而防止系统在应用程序运行时进入睡眠或关闭显示器
这不是一个完美的解决方案,但我认为这对您来说不是问题:
SetThreadExecutionState函数不能用于防止用户将计算机置于休眠状态。应用程序应该尊重用户在关闭笔记本电脑上的盖子或按下电源按钮时需要某种行为
Windows 8连接待机功能也是您可能需要考虑的事项。查看与电源相关的API,我们可以找到PowerRequestSystemRequired
的描述:
系统在用户不活动一段时间后继续运行而不是进入睡眠状态。
此请求类型不适用于能够连接待机的系统。应用程序应该使用PowerRequestExecutionRequired请求。
如果您正在处理平板电脑和其他小型设备,那么您可以尝试使用PowerRequestExecutionRequired
拨打PowerSetRequest
以阻止此情况,尽管对此的描述也不理想:
调用进程继续运行,而不是由进程生存期管理机制暂停或终止。允许进程运行的时间和长度取决于操作系统和电源策略设置。
您可能还想使用ShutdownBlockReasonCreate
,但我不确定它是否会阻止睡眠/休眠。
答案 1 :(得分:0)
感谢Anders指出我正确的方向 - 我在golang中放了一个最小的例子(见下文)。
注意:轮询重置计时器似乎是唯一可靠的方法,我发现当尝试与连续标志结合时,它只会生效大约30秒(不明白为什么),已经说过对此进行轮询例子是过度的,可能会增加到10分钟(因为最小休眠时间是15分钟)
另外,仅供参考,这是一个特定于Windows的示例:
package main
import (
"log"
"syscall"
"time"
)
// Execution States
const (
EsSystemRequired = 0x00000001
EsContinuous = 0x80000000
)
var pulseTime = 10 * time.Second
func main() {
kernel32 := syscall.NewLazyDLL("kernel32.dll")
setThreadExecStateProc := kernel32.NewProc("SetThreadExecutionState")
pulse := time.NewTicker(pulseTime)
log.Println("Starting keep alive poll... (silence)")
for {
select {
case <-pulse.C:
setThreadExecStateProc.Call(uintptr(EsSystemRequired))
}
}
}
以上是在胜利7和10上测试的(未在Win 8上测试过 - 假设也在那里工作)。
任何用户睡眠请求都将覆盖此方法,其中包括关闭笔记本电脑盖子等操作(除非电源管理设置从默认设置更改)
以上是我申请的明智行为。