防止睡眠模式python(python上的Wakelock)
- 2024-11-08 09:04:00
- admin 原创
- 25
问题描述:
如何在不使用不同操作系统(Ubuntu、Windows……)上的额外应用程序的情况下防止 Python 进入睡眠模式,但在大多数情况下我需要 Linux 解决方案
我正在开发一款运行时间很长的应用。它占用了大约 80% 的 CPU,因此用户只需启动该应用,然后离开键盘即可。因此,我认为我需要一些类似系统 API 或库的东西来锁定睡眠模式。我确信它存在。例如,如果您在操作系统上打开任何视频播放器,您的(PC、笔记本电脑)将不会进入睡眠模式,浏览器中也是如此。
此外,Android( WakeLock)和Windows (SetThreadExecutionState)中也有同样的东西
解决方案 1:
在谷歌上搜索解决方案时,没有可用的软件包,所以我决定将其打包放到 PyPI:wakepy。我获得了跨平台支持的 PR,目前 wakepy 支持 Windows、Linux 和 macOS。
命令行界面
python -m wakepy [-p]
使用可选-p
标志将使用演示模式,保持屏幕开启并解锁。
Python API
防止睡眠:
from wakepy import keep
with keep.running():
# do stuff that takes long time
防止屏幕保护程序/屏幕锁定(和睡眠):
from wakepy import keep
with keep.presenting():
# do stuff that takes long time
解决方案 2:
我遇到过类似的情况,一个进程执行时间太长,导致窗口休眠。为了解决这个问题,我写了一个脚本。
下面这段简单的代码可以防止这个问题。使用时,它会要求 Windows 在脚本运行时不要进入睡眠状态。(在某些情况下,例如电池电量耗尽时,Windows 会忽略您的请求。)
class WindowsInhibitor:
'''Prevent OS sleep/hibernate in windows; code from:
https://github.com/h3llrais3r/Deluge-PreventSuspendPlus/blob/master/preventsuspendplus/core.py
API documentation:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa373208(v=vs.85).aspx'''
ES_CONTINUOUS = 0x80000000
ES_SYSTEM_REQUIRED = 0x00000001
def __init__(self):
pass
def inhibit(self):
import ctypes
print("Preventing Windows from going to sleep")
ctypes.windll.kernel32.SetThreadExecutionState(
WindowsInhibitor.ES_CONTINUOUS | \n WindowsInhibitor.ES_SYSTEM_REQUIRED)
def uninhibit(self):
import ctypes
print("Allowing Windows to go to sleep")
ctypes.windll.kernel32.SetThreadExecutionState(
WindowsInhibitor.ES_CONTINUOUS)
要运行脚本,只需:
import os
osSleep = None
# in Windows, prevent the OS from sleeping while we run
if os.name == 'nt':
osSleep = WindowsInhibitor()
osSleep.inhibit()
# do slow stuff
if osSleep:
osSleep.uninhibit()
解决方案 3:
创建示例 TK 应用程序以保持 Windows 处于唤醒状态
import tkinter as tk
import ctypes
import sys
def display_on():
global root
print("Always On")
ctypes.windll.kernel32.SetThreadExecutionState(0x80000002)
root.iconify()
def display_reset():
ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
sys.exit(0)
root = tk.Tk()
root.geometry("200x60")
root.title("Display App")
frame = tk.Frame(root)
frame.pack()
button = tk.Button(frame,
text="Quit",
fg="red",
command=display_reset)
button.pack(side=tk.LEFT)
slogan = tk.Button(frame,
text="Always ON",
command=display_on)
slogan.pack(side=tk.LEFT)
root.mainloop()
解决方案 4:
我为它创建了一个名为stay-awake
PyPi:https://pypi.org/project/stay-awake/
Github:https ://github.com/singhsidhukuldeep/stay-awake
Stay-Awake 是一个简单的平台独立 Python 包,可让您的系统保持唤醒状态而不影响工作流程!
这会影响工作流程吗?
不,只有当您不进行任何鼠标移动时才会触发此操作!
有 GUI 吗?
这旨在成为一个轻量级解决方案,所以到目前为止它只有一个 CLI!
它是如何工作的?
如果在 60 秒内您没有移动鼠标,此脚本将自动随机移动鼠标约 1 到 4 个像素。不会有任何鼠标位移!如果您正在工作,这将完全不产生任何效果!
设置
安装包
pip3 install stay-awake
跑步
python3 -m stay-awake
您还可以指定自定义超时时间,例如:5 分钟(默认为 1 分钟)
python3 -m stay-awake 5
解决方案 5:
根据我在互联网上找到的多种方法,我提出了以下模块。特别感谢@mishsx 提供的Windows
解决方法。
使用它非常简单。您可以选择使用装饰器方法standby_lock
或通过StandbyLock
上下文管理器:
## decorator
@standby_lock
def foo(*args, **kwargs):
# do something lazy here...
pass
## context manager
with StandbyLock():
# ...or do something lazy here instead
pass
foo
在执行期间,您的系统将保持唤醒状态。
注意:仍有一些注意事项,因为Linux
可能需要sudo
特权并且OS X
(Darwin
)尚未测试。
from functools import wraps
import platform
class MetaStandbyLock(type):
"""
"""
SYSTEM = platform.system()
def __new__(cls, name: str, bases: tuple, attrs: dict) -> type:
if not ('inhibit' in attrs and 'release' in attrs):
raise TypeError("Missing implementations for classmethods 'inhibit(cls)' and 'release(cls)'.")
else:
if name == 'StandbyLock':
cls._superclass = super().__new__(cls, name, bases, attrs)
return cls._superclass
if cls.SYSTEM.upper() in name.upper():
if not hasattr(cls, '_superclass'):
raise ValueError("Class 'StandbyLock' must be implemented.")
cls._superclass._subclass = super().__new__(cls, name, bases, attrs)
return cls._superclass._subclass
else:
return super().__new__(cls, name, bases, attrs)
class StandbyLock(metaclass=MetaStandbyLock):
"""
"""
_subclass = None
@classmethod
def inhibit(cls):
if cls._subclass is None:
raise OSError(f"There is no 'StandbyLock' implementation for OS '{platform.system()}'.")
else:
return cls._subclass.inhibit()
@classmethod
def release(cls):
if cls._subclass is None:
raise OSError(f"There is no 'StandbyLock' implementation for OS '{platform.system()}'.")
else:
return cls._subclass.release()
def __enter__(self, *args, **kwargs):
self.inhibit()
return self
def __exit__(self, *args, **kwargs):
self.release()
class WindowsStandbyLock(StandbyLock):
"""
"""
ES_CONTINUOUS = 0x80000000
ES_SYSTEM_REQUIRED = 0x00000001
INHIBIT = ES_CONTINUOUS | ES_SYSTEM_REQUIRED
RELEASE = ES_CONTINUOUS
@classmethod
def inhibit(cls):
import ctypes
ctypes.windll.kernel32.SetThreadExecutionState(cls.INHIBIT)
@classmethod
def release(cls):
import ctypes
ctypes.windll.kernel32.SetThreadExecutionState(cls.RELEASE)
class LinuxStandbyLock(metaclass=MetaStandbyLock):
"""
"""
COMMAND = 'systemctl'
ARGS = ['sleep.target', 'suspend.target', 'hibernate.target', 'hybrid-sleep.target']
@classmethod
def inhibit(cls):
import subprocess
subprocess.run([cls.COMMAND, 'mask', *cls.ARGS])
@classmethod
def release(cls):
import subprocess
subprocess.run([cls.COMMAND, 'unmask', *cls.ARGS])
class DarwinStandbyLock(metaclass=MetaStandbyLock):
"""
"""
COMMAND = 'caffeinate'
BREAK = b''
_process = None
@classmethod
def inhibit(cls):
from subprocess import Popen, PIPE
cls._process = Popen([cls.COMMAND], stdin=PIPE, stdout=PIPE)
@classmethod
def release(cls):
cls._process.stdin.write(cls.BREAK)
cls._process.stdin.flush()
cls._process.stdin.close()
cls._process.wait()
def standby_lock(callback):
""" standby_lock(callable) -> callable
This decorator guarantees that the system will not enter standby mode while 'callable' is running.
"""
@wraps(callback)
def new_callback(*args, **kwargs):
with StandbyLock():
return callback(*args, **kwargs)
return new_callback
解决方案 6:
Keep.Awake 中的逻辑将解决您在 ubuntu 或任何运行 Gnome(包括 Unity 的新旧版本)的 Linux 发行版上的问题,适用于 Wayland 和 X。它易于使用。
我在这里发布了类似问题的解决方案:https ://askubuntu.com/a/1231975/183131
因此从逻辑上来说,请执行以下操作:
通过 subprocess.Popen(...) 使用 DBus 命令清除睡眠/挂起计数器。
使用 psutil.cpu_percent() 定期查询 CPU 使用量,或者在程序完成其工作后放置逻辑以重新设置睡眠配置。
您可以在此处查看代码以获取有关如何修改代码的详细信息或提示: https: //launchpad.net/keep.awake
或者,您也可以在运行 CPU 密集型程序的 Linux 机器上运行 keepawake.py,它就会解决您的问题!它真的有效!
取自网页的示例用法:
要作为后台服务运行并将最低 CPU 负载设置为 13%:
nohup ./keepawake.py -c 13 -r > /dev/null 2>&1 &
作为后台服务运行,并在确定用户处于空闲状态之前将 15 分钟(900 秒)设置为用户活动空闲时间:
nohup ./keepawake.py -u 900 -r > /dev/null 2>&1 &
作为后台服务运行并将最小网络流量设置为 5KB(5120 字节):
nohup ./keepawake.py -s 5120 -r > /dev/null 2>&1 &
作为后台服务运行,并将计划设置为 1 小时后睡眠/挂起(仅当确定用户活动、CPU 和网络流量都处于空闲状态时才设置此值):
nohup ./keepawake.py -w 3600 -r > /dev/null 2>&1 &
要一次性运行上述所有设置(网络、CPU、用户空闲、睡眠计划),并将日志文件路径设置为“/home/$USER/sleep/log/Keep.Awake/”,并显示详细输出:
nohup ./keepawake.py -s 5120 -c 13 -u 900 -w 3600 -l /home/$USER/sleep/log/Keep.Awake/ -v Detail -r > /dev/null 2>&1 &
解决方案 7:
此代码用于每n分钟移动一次鼠标光标以保持系统保持唤醒。
首先安装pyautogui
Python。
运行以下代码:
import pyautogui
import time
import sys
from datetime import datetime
pyautogui.FAILSAFE = False
numMin = None
if ((len(sys.argv)<2) or sys.argv[1].isalpha() or int(sys.argv[1])<1):
numMin = 2 # move cursor after numMin minutes
else:
numMin = int(sys.argv[1])
while(True):
x=0
while(x<numMin):
time.sleep(60)
x+=1
for i in range(0,50):
pyautogui.moveTo(i*6+50,i*4)
pyautogui.moveTo(1,1)
for i in range(0,3):
pyautogui.press("shift")
print("Movement made at {}".format(datetime.now().time()))
解决方案 8:
您还可以使用 Caffeine+,这是一个小型托盘应用程序,可以让系统保持唤醒状态,而无需模拟键盘事件或完全干扰用户界面。https ://enemydevelopment.com/software/caffeine
解决方案 9:
在 Windows 上,不确定这是否会对任何人有所帮助,但上述方法对我不起作用。最终起作用的是运行第二个进程,该进程每 30 秒不断调用“shutdown /a”(中止关机)。Windows 说您大约有 1 分钟的时间来执行此操作,所以这就是 30 秒的原因。
完全愚蠢的解决方案,但无论如何,这是一个非常愚蠢的问题,没有操作系统提供的解决方案。
import subprocess
from time import sleep
def main():
while(True):
p = subprocess.Popen("shutdown /a", stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
res = p.communicate()
p.kill()
sleep(30) # sleep 30 sec.
if __name__ == "__main__":
main()
解决方案 10:
GUI 应用程序使窗口保持活动状态
Python3
安装库
pip install pywin32
将以下代码保存为alive.pyw
文件
from ctypes import windll, wintypes, byref, c_uint, sizeof, Structure
import tkinter as tk
import ctypes
import sys
import threading
import time
import win32api
import win32con
stop_threads = True
SET_IDLE_TIME = 40 #in seconds
class LASTINPUTINFO(Structure):
_fields_ = [
('cbSize', c_uint),
('dwTime', c_uint),
]
def get_idle_duration():
lastInputInfo = LASTINPUTINFO()
lastInputInfo.cbSize = sizeof(lastInputInfo)
windll.user32.GetLastInputInfo(byref(lastInputInfo))
millis = windll.kernel32.GetTickCount() - lastInputInfo.dwTime
return millis / 1000.0
def press_key_2():
global stop_threads
while True:
if not stop_threads:
break
idle_time = get_idle_duration() #seconds
time.sleep(0.1)
if idle_time < SET_IDLE_TIME:
continue
print("in ideal state pressing cltr")
win32api.keybd_event(ord('x'), 0, win32con.KEYEVENTF_EXTENDEDKEY, 0)
#---------------- Monitor threads ------------------------------
t1 = threading.Thread(target=press_key_2, name='t1')
t1.daemon = True
#----------------- TK functions ----------------------
def display_on():
global tk, t1, stop_threads
stop_threads = True
print("Always On")
ctypes.windll.kernel32.SetThreadExecutionState(0x80000002)
root.iconify()
t1.start()
# t2.start()
def display_reset():
print("quit pressed")
global stop_threads
stop_threads = False
ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
sys.exit(0)
root = tk.Tk()
root.geometry("200x110")
root.title("Display App")
frame = tk.Frame(root)
frame.pack()
var = tk.StringVar()
label = tk.Label(frame, textvariable = var)#, bd = 5, justify = tk.RIGHT, padx = 10, pady = 10)
var.set("")
button = tk.Button(frame,
text="Quit",
fg="red",
command=display_reset)
slogan = tk.Button(frame,
text="Always ON",
command=display_on)
label.pack(side=tk.BOTTOM,padx=0, pady=0)
slogan.pack(side=tk.LEFT,padx=15, pady=20)
button.pack(side=tk.LEFT,padx=15, pady=20)
root.mainloop()
ctypes.windll.kernel32.SetThreadExecutionState(0x80000000)
解决方案 11:
我编写了这段 Python 代码,它不仅可以让你的屏幕保持活动状态,还可以让你在不打扰你的情况下工作。基本上,你不必打开和关闭它。你可以让它保持运行并同时工作 -
这是 Python 代码 - https://github.com/sudhanshuism/keepPCAliveUserEnabled
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件