假设您在会话总线(每个用户总线)上有一个 DBus 服务。您的服务可能通过文件启动/etc/xdg/autostart/*
,也可能在某个应用首次尝试使用您的知名服务名称时启动。无论哪种方式,我们假设 DBus 会话总线是启动您的服务的进程。
然后用户注销。那么会发生什么?DBus 会发送任何可操作的信息吗?特别兴趣小组<foo> 向您的服务发出信号,还是直接发送给SIGKILL
?还有其他方法可以知道用户正在注销吗?基本上,我需要运行一些清理操作,其中包括终止以 和 开头的子subprocess.Popen
进程multiprocessing
。
现在,在你说“Popen
并且multiprocessing
是邪恶的,不要使用它们”之前,在我目前的实验中,我不是使用它们。我只是想弄清楚 Python DBus 服务如何挂接到允许它运行清理操作的东西上,无论整体架构如何。
有什么建议吗?有什么例子吗?请注意,我的示例将在GObject.MainLoop
Ubuntu Precise(或 Quantal)上使用 Python3 运行。
答案1
您可以做这样的事情:
bus = dbus.SessionBus()
bus.call_on_disconnection(your_method_to_do_stuff)
或者您可以连接到接口NameLost
上的信号org.FreeDesktop.DBus
。前者不允许您传递其他参数,并且您的方法只能将总线连接对象本身作为参数。后者稍微复杂一些,但似乎也不允许您自行传递其他参数,并且您只能使用信号本身发送的参数,在本例中是您的进程以前拥有的消息总线名称的字符串。
另一方面,如果您的流程在此之后确实仍然存在,那么理论上您SIGKILL
也应该在某个时间点获得。
答案2
如果你只关心在 GNOME 和 Unity 下运行,你应该能够挂接到会话管理器DBus 接口QueryEndSession
。这不仅会通过和信号向您发出“即将注销”消息EndSession
,而且还允许您阻止注销/关机,直到您完成清理工作(如果您愿意),通过EndSessionResponse
。
我不确定 KDE 在多大程度上实现了兼容接口。