如何通过编程阻止Ubuntu在Python程序运行时进入睡眠模式?
解决Ubuntu下Python运行时阻止系统睡眠的问题
太懂这种跑长时间ML训练被系统睡眠打断的憋屈了!尤其是Ray RLlib这种后台跑的任务,就算CPU/GPU满负载,Ubuntu没交互还是会乖乖按电源设置休眠。给你几个Python里就能搞定的方案,不用每次手动改系统设置:
方案1:用xdg-screensaver(通用桌面环境)
这个工具是Freedesktop标准的一部分,GNOME、KDE、Xfce这些主流桌面都支持,能临时禁用屏幕保护和自动睡眠,训练完自动恢复。
import subprocess from contextlib import contextmanager @contextmanager def prevent_sleep(): try: # 暂停屏幕保护及自动睡眠 subprocess.run(["xdg-screensaver", "suspend"], check=True) yield finally: # 无论训练成功/失败,都恢复原有设置 subprocess.run(["xdg-screensaver", "resume"], check=True) # 用上下文管理器包裹训练代码 if __name__ == "__main__": with prevent_sleep(): # 这里放你的Ray RLlib训练代码 # ray.init() # trainer = ... # trainer.train() print("Running long training task...")
用上下文管理器的好处是绝对不会忘记恢复设置——哪怕训练中途报错崩溃,finally块也会执行,不会让系统一直保持不休眠状态。
方案2:针对GNOME桌面(Ubuntu默认)
如果你的Ubuntu用的是默认GNOME桌面,可以直接用gsettings临时修改电源设置,比xdg-screensaver更精准控制电源行为:
import subprocess from contextlib import contextmanager @contextmanager def prevent_gnome_sleep(): # 先保存原有电源设置,方便后续恢复 original_dim = subprocess.check_output( ["gsettings", "get", "org.gnome.settings-daemon.plugins.power", "idle-dim"] ).decode().strip() original_ac_sleep = subprocess.check_output( ["gsettings", "get", "org.gnome.settings-daemon.plugins.power", "sleep-inactive-ac-type"] ).decode().strip() try: # 关闭空闲时屏幕变暗 subprocess.run( ["gsettings", "set", "org.gnome.settings-daemon.plugins.power", "idle-dim", "false"], check=True ) # 接通电源时禁止自动睡眠 subprocess.run( ["gsettings", "set", "org.gnome.settings-daemon.plugins.power", "sleep-inactive-ac-type", "'nothing'"], check=True ) yield finally: # 恢复原有设置 subprocess.run( ["gsettings", "set", "org.gnome.settings-daemon.plugins.power", "idle-dim", original_dim], check=True ) subprocess.run( ["gsettings", "set", "org.gnome.settings-daemon.plugins.power", "sleep-inactive-ac-type", original_ac_sleep], check=True ) # 包裹训练代码 if __name__ == "__main__": with prevent_gnome_sleep(): # 你的Ray RLlib训练逻辑 print("Running GNOME-based training...")
这个方法会直接修改GNOME的电源配置项,训练结束后完全恢复原状,不会影响你平时的电源习惯。
方案3:系统级抑制(systemd-inhibit,最可靠)
如果你的Ubuntu用的是systemd(现在几乎所有主流Linux发行版都是),可以用systemd-inhibit创建一个系统级的睡眠抑制锁——不管桌面环境是什么,这个方法都能生效,是最稳定的选择。
import subprocess from contextlib import contextmanager @contextmanager def systemd_prevent_sleep(): # 启动一个抑制睡眠的后台进程 inhibit_proc = subprocess.Popen([ "systemd-inhibit", "--what=sleep:idle", # 阻止睡眠和空闲休眠 "--who=MLTrainingScript", # 标识来源,方便系统查看 "--why=Prevent sleep during long machine learning training", # 抑制原因 "--mode=block", # 强制阻止睡眠 "sleep", "infinity" # 保持进程运行,直到我们终止它 ]) try: yield finally: # 终止抑制进程,解除睡眠锁 inhibit_proc.terminate() inhibit_proc.wait() # 包裹训练代码 if __name__ == "__main__": with systemd_prevent_sleep(): # 你的Ray RLlib训练任务 print("Running system-level protected training...")
systemd-inhibit会告诉systemd:“这个进程还在跑,别让系统睡觉”,直到我们主动终止那个sleep infinity进程。就算桌面环境的电源设置有冲突,这个系统级的抑制也能优先生效。
内容的提问来源于stack exchange,提问作者FlorianH
相关产品推荐
相关产品推荐

