1 回答
TA贡献2011条经验 获得超2个赞
尽管我相信您最好使用侦听端口的服务器 - 客户端类型的解决方案,但您要问的是 100% 可能使用signal
和os
库。这种方法不适用于多线程程序,但是因为信号仅由 python 中的父线程处理。此外,windows 不会以相同的方式实现信号,因此选项更加有限。
信号
“客户端”进程可以使用os.kill(pid, signal)
. 您必须查看可用信号并确定要使用哪个信号(signal.NSIG
可能是一个不错的选择,因为它不应该影响任何其他默认行为)。
启动时的“守护进程”进程必须注册一个处理程序,以便在它接收到您选择的信号时执行什么操作。处理程序是一个您必须定义的函数,它接收接收到的信号本身以及 executon ( def handler(signum, frame):
)的当前堆栈帧。如果你只用这个处理程序做一件事,并且它不需要知道它被调用时发生了什么,你可以忽略这两个参数。然后您必须使用signal.signal
ex:注册处理程序signal.signal(signal.NSIG, handler)
。
从那里你会想找到一些合适的方法来等待下一个信号而不消耗太多资源。这可以像循环os.sleep
命令一样简单,或者您可以尝试变得花哨。我不确定 100% 从信号处理程序返回时如何恢复执行,因此您可能需要关注递归深度(即,确保每次处理信号时都不要递归,否则您将永远能够在需要重新启动之前处理有限数量的信号)。
服务器
让进程监听端口(通常称为服务器,但在功能上与您的“守护进程”描述相同)而不是监听操作系统信号有几个主要优点。
端口能够在信号只能触发事件的地方发送数据
端口更相似跨平台
端口在多线程中玩得很好[r]
端口使通过网络发送消息变得容易(即:从手机创建提醒并在 PC 上执行)
一次等待多件事
为了解决同时等待多个进程的需要(侦听输入以及等待发送下一个通知),您有很多选择:
信号实际上可能是一个很好的用例,因为
signal.SIGALRM
它可以用作方便地重新设置的闹钟(如果您使用的是 UNIX)。您可以像以前一样设置处理程序,只需为下一个通知设置警报。设置警报后,您可以简单地继续在端口上侦听新任务。如果有新任务进入,再次设置警报将覆盖现有任务,因此处理程序需要检索下一个排队通知并在第一个任务完成后重新设置警报。线程既可以用于轮询通知任务队列,也可以创建一个单独的线程来等待每个任务。这不是一个特别优雅的解决方案,但它会有效且易于实施。
最优雅的解决方案可能是使用
asyncio
协程,但是我对 asyncio 不太精通,并且承认它们比线程更令人困惑。
添加回答
举报