如何知道系统是否刚刚从睡眠状态中唤醒
How to know if system has just woken up from a mem sleep?
我有一个在Linux上运行的Qt应用程序。
用户可以使用此应用程序将系统切换到内存休眠状态。
切换到mem睡眠是微不足道的,但在用户空间捕捉唤醒事件不是。
我目前的解决方案是使用一个无限循环来捕获内存休眠,这样当系统唤醒时,我的应用程序总是从一个可预测的点继续。
下面是我的代码:void MainWindow::memSleep()
{
int fd;
fd = ::open("/sys/power/state", O_RDWR);// see update 1)
QTime start=QTime::currentTime();
write(fd,"mem",3); // command that triggers mem sleep
while(1){
usleep(5000); // delay 5ms
const QTime &end=QTime::currentTime();// check system clock
if(start.msecsTo(end)>5*2){// if time gap is more than 10ms
break; // it means this thread was frozen for more
} // than 5ms, indicating a wake up after a sleep
start=end;
}
:: close(fd); // the end of this function marks a wake up event
}
我把这个方法描述为对这个问题的评论,有人指出这不是一个好的解决方案,我同意。
问题:是否有一个C API,我可以用它来捕捉唤醒事件?
更新:
1)什么是睡眠?
https://www.kernel.org/doc/Documentation/power/states.txt内核通常最多支持四种系统睡眠状态,尽管只有三种它们中的一些依赖于平台支持代码来实现底层细节
状态由字符串表示,这些字符串可以读或写到<<strong>/sys/电力/状态/strong>文件。这些字符串可以是"mem", "standby", "freeze"answers"disk",其中最后一个总是表示休眠(suspend to disk)和其余选项的含义取决于relative_sleep_states命令行参数。
2)为什么我想要捕捉唤醒事件?
因为一些硬件需要在唤醒后重置。硬件输入设备在系统唤醒后会产生错误的输入事件,所以必须在睡觉前禁用(容易),醒来后启用(这个问题)。
这应该/可以由内核中的驱动程序处理,我可以访问,或者在硬件中固定,我的团队可以做,但没有时间去做。(为什么我,一个应用程序开发人员,需要在用户空间修复它)
3)约束这是嵌入式linux,内核2.6.37,arch:arm, march:omap2,发行版:arago。它不像PC发行版那样方便添加包,也没有ACPI。而且内核2.6.37对内存睡眠的支持还不成熟
PCI设备的Linux设备驱动程序可以选择性地处理suspend和resume,据推测,内核分别在系统挂起之前和从挂起恢复之后调用它们。PCI入口点在struct pci_driver
.
您可以编写并安装一个简单的设备驱动程序,它除了感知恢复操作并向任何感兴趣的进程提供指示外,什么也不做。最简单的可能是支持一个文件read(),它在感知到resume时返回单个字节。该程序只需要打开设备,并留下一个线程卡住读取单个字符。当读取成功时,系统刚刚恢复。
更重要的是,如果你的应用程序正在处理的设备有设备驱动程序,那么这些驱动程序应该被更新,以便对resume做出适当的反应。
当系统从睡眠中醒来时,它应该生成一个ACPI事件,因此acpid应该让您检测并处理该事件:通过/etc/acpi/events
脚本,通过连接到/var/run/acpid.socket
,或通过使用acpi_listen。(acpi_listen
应该是一个简单的方法来测试如果这将工作)
检查pm-utils
,您可以在/etc/pm/sleep.d
上放置钩子在钩子中,你可以传递信号给你的应用程序,例如通过kill或任何IPC。
你也可以让pm-utils做计算机挂起,IMO更兼容不同的配置。
编辑:我不熟悉arago
,但是pm-utils是arch和ubuntu自带的。还要注意,在使用systemd
的新系统上,pm-utils已经过时了,您应该将钩子放在systemd
上。
REF: systemd power events
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- OSX MetalKit CVMetalTextureCacheCreateTextureFromImage失败,状态:
- std::future_error:无关联状态
- 如何避免LED在循环状态变化中闪烁?
- boost 是否有按特殊类型值编码状态"compact optional"?
- 为什么系统函数总是在C++中返回已转移的退出状态?
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 当可输入框在窗口中处于活动状态时获得通知的任何方法
- 检查两个节点在子节点上是否具有相同状态的更优雅的方法
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- 将有状态的 lambda 传递到 C 样式函数中,而无需上下文参数
- 在 nullptr 上调用无状态类的非静态成员函数是否合法?
- 编译问题:在函数"_start"中:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- C++部分概念 id:显式模板规范顺序/第一个参数的特殊状态的原因是什么?
- 试图在崇高中奔跑. 错误 已发生: 收集2.exe: 错误: ld 返回 1 退出状态
- 列出可以通过C++和禁用/启用它们将系统从睡眠状态唤醒的设备?
- 如何知道系统是否刚刚从睡眠状态中唤醒
- 唤醒处于睡眠状态的QThread