我希望防止同一个长时间运行的Python命令行脚本同时运行多个实例,并且我希望新实例能够在自杀之前将数据发送给原始实例。如何以跨平台的方式实现这一点?
具体而言,我想实现以下行为:
1.从命令行启动“foo.py”,它将持续运行很长时间--天或周,直到机器重新启动或父进程将其杀死。
2.每隔几分钟就会再次启动相同的脚本,但使用不同的命令行参数。
3.当启动时,脚本应该查看是否有其他实例正在运行。
4.如果有其他实例正在运行,则第二个实例应将其命令行参数发送给第一个实例,然后第二个实例应退出。
5.如果收到另一个脚本发送的命令行参数,实例#1应该启动一个新线程,并开始执行实例#2要执行的工作。
因此,我正在寻找两件事:Python程序如何知道另一个实例正在运行,然后一个Python命令行程序如何与另一个通信?
使这更加复杂的是,同一个脚本需要在Windows和Linux上运行,因此理想情况下的解决方案仅使用Python标准库而不使用任何特定于操作系统的调用。虽然如果我需要有一个Windows代码路径和一个*nix代码路径(并且在我的代码中有一个大的if语句来选择其中一个),那么如果“同一代码”解决方案不可行,那也没关系。
我意识到我可能可以想出一个基于文件的方法(例如,实例#1监视更改的目录,每个实例在要执行工作时将文件放入该目录),但我有点担心在非正常关闭机器后清理这些文件。我最好能够使用内存中的解决方案。但是我还是很灵活的,如果持久性文件为基础的方法是唯一的方法,我愿意采用该选项。更多细节:我正在尝试这样做是因为我们的服务器使用一种监控工具来运行Python脚本以收集监控数据(例如数据库查询或Web服务调用的结果),然后该监控工具会对其进行索引以备将来使用。有些脚本启动非常昂贵,但在启动后运行起来很便宜(例如建立数据库连接与执行查询操作)。因此,我们选择将它们保持在无限循环中,直到父进程杀死它们。
这样做效果很好,但在较大的服务器上,即使每20分钟收集一次数据,也可能会运行100个相同的脚本实例。这会对RAM、数据库连接限制等造成严重破坏。我们想要从具有1个线程的100个进程切换到一个具有100个线程的进程,每个线程执行以前一个脚本完成的任务。
但是,改变如何通过监控工具调用脚本是不可能的。我们需要保持调用方式不变(使用不同的命令行参数启动进程),但是改变脚本以识别另一个脚本已经在运行,并且让“新”脚本将其工作指令(从命令行参数)发送到“旧”脚本。
顺便说一下,这不是我想逐个脚本执行的操作。相反,我想将此行为打包成一个库,许多脚本作者可以利用 - 我的目标是使脚本作者编写简单的单线程脚本,这些脚本不知道多实例问题,并在底层处理多线程和单实例。
具体而言,我想实现以下行为:
1.从命令行启动“foo.py”,它将持续运行很长时间--天或周,直到机器重新启动或父进程将其杀死。
2.每隔几分钟就会再次启动相同的脚本,但使用不同的命令行参数。
3.当启动时,脚本应该查看是否有其他实例正在运行。
4.如果有其他实例正在运行,则第二个实例应将其命令行参数发送给第一个实例,然后第二个实例应退出。
5.如果收到另一个脚本发送的命令行参数,实例#1应该启动一个新线程,并开始执行实例#2要执行的工作。
因此,我正在寻找两件事:Python程序如何知道另一个实例正在运行,然后一个Python命令行程序如何与另一个通信?
使这更加复杂的是,同一个脚本需要在Windows和Linux上运行,因此理想情况下的解决方案仅使用Python标准库而不使用任何特定于操作系统的调用。虽然如果我需要有一个Windows代码路径和一个*nix代码路径(并且在我的代码中有一个大的if语句来选择其中一个),那么如果“同一代码”解决方案不可行,那也没关系。
我意识到我可能可以想出一个基于文件的方法(例如,实例#1监视更改的目录,每个实例在要执行工作时将文件放入该目录),但我有点担心在非正常关闭机器后清理这些文件。我最好能够使用内存中的解决方案。但是我还是很灵活的,如果持久性文件为基础的方法是唯一的方法,我愿意采用该选项。更多细节:我正在尝试这样做是因为我们的服务器使用一种监控工具来运行Python脚本以收集监控数据(例如数据库查询或Web服务调用的结果),然后该监控工具会对其进行索引以备将来使用。有些脚本启动非常昂贵,但在启动后运行起来很便宜(例如建立数据库连接与执行查询操作)。因此,我们选择将它们保持在无限循环中,直到父进程杀死它们。
这样做效果很好,但在较大的服务器上,即使每20分钟收集一次数据,也可能会运行100个相同的脚本实例。这会对RAM、数据库连接限制等造成严重破坏。我们想要从具有1个线程的100个进程切换到一个具有100个线程的进程,每个线程执行以前一个脚本完成的任务。
但是,改变如何通过监控工具调用脚本是不可能的。我们需要保持调用方式不变(使用不同的命令行参数启动进程),但是改变脚本以识别另一个脚本已经在运行,并且让“新”脚本将其工作指令(从命令行参数)发送到“旧”脚本。
顺便说一下,这不是我想逐个脚本执行的操作。相反,我想将此行为打包成一个库,许多脚本作者可以利用 - 我的目标是使脚本作者编写简单的单线程脚本,这些脚本不知道多实例问题,并在底层处理多线程和单实例。