检测进程是否已在运行并与我协作

2024-06-01 07:30:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图创建一个程序,它启动一个进程池,比如说,5个进程,执行一些操作,然后退出,但让5个进程保持打开状态。以后用户可以再次运行该程序,而不是启动新的进程,而是使用现有的5。基本上是一个生产者-消费者模型,其中:

  1. 生产者的数量各不相同。在
  2. 消费者的数量是不变的。在
  3. 制作者可以在不同的时间由不同的程序甚至不同的用户启动。在

我使用的是内置的multiprocessing模块,目前在Python2.6.4中,但最终打算迁移到3.1.1。在

下面是一个基本的使用场景:

  1. 开始状态-没有进程正在运行。在
  2. 用户启动program.py operation-一个生产者,五个消费者在运行。在
  3. 操作完成-五个用户正在运行。在
  4. 用户启动program.py operation-一个生产者,五个消费者在运行。在
  5. 用户启动program.py operation-两个生产者,五个消费者在运行。在
  6. 操作完成-一个生产商,五个消费者在运行。在
  7. 操作完成-五个用户正在运行。在
  8. 用户启动program.py stop并完成-没有进程在运行。在
  9. 用户启动program.py start并完成-五个消费者正在运行。在
  10. 用户启动program.py operation-一个生产者,五个消费者在运行。在
  11. 操作完成-五个用户正在运行。在
  12. 用户启动program.py stop并完成-没有进程在运行。在

我的问题是我不知道从哪里开始:

  1. 正在检测使用者进程是否正在运行。在
  2. 从以前不相关的程序中访问它们。在
  3. 以跨平台的方式进行1和2。在

一旦我能做到这一点,我就知道如何管理流程。必须有一些可靠的方法来检测现有的进程,因为我见过Firefox这样做是为了防止Firefox的多个实例运行,但是我不知道如何在Python中做到这一点。在


Tags: 用户py模型程序数量进程状态时间
3条回答

看看这些不同的服务发现机制:http://en.wikipedia.org/wiki/Service_discovery

其基本思想是,当用户启动服务时,他们将各自注册一个服务。制作人将在开始时完成发现过程。如果它找到了消费者,它就与他们绑定。如果它找不到它们,它就会启动新的消费者。在大多数这些系统中,服务通常也可以发布属性,因此您可以让每个使用者唯一地标识自己,并将其他信息提供给发现生产者。在

Bonjour/zeroconf是一个非常好的跨平台支持。您甚至可以将Safari配置为在您的本地网络上显示zeroconf服务,这样您就可以使用它来调试针对消费者的服务广告。这种方法的一个优点是,您可以轻松地在不同的机器上运行生产者而不是消费者。在

您需要本地系统上的客户机-服务器模型。可以使用TCP/IP套接字在客户机和服务器之间进行通信,但是如果不需要通过网络进行通信,那么使用本地命名管道会更快。在

如果我理解正确,对您的基本要求是:
1生产者应该能够产生消费者,如果没有已经存在。
2生产者应该能够与消费者沟通。
三。生产者应该能够找到已有的消费者并与他们沟通。
4即使生产者完成任务,消费者也应该继续运行。
5不止一个生产商应该能够与消费者沟通。

让我们逐一解决这些问题:

(1)是一个简单的进程创建问题,除了使用者(子)进程应该继续运行,即使生产者(父)退出。见下文(4)。在

(2)生产者可以使用named pipes与消费者通信。请参见os.mkfifo()mkfifo()的unix man page创建命名管道。在

(3)当使用者进程开始运行时,需要从已知路径中的使用者进程创建命名管道。生产商可以通过在同一地点寻找这一知名管道来查明是否有消费者在运行。如果管道不存在,则没有使用者在运行,生产者可以生成这些管道。在

{4}你需要一个像a5这样的进程来使用。请参见setsid()的unixman page。在

(5)这个很棘手。多个生产者可以使用同一个命名管道与消费者通信,但是如果您想可靠地标识哪个生产者发送了数据,或者如果您想防止来自不同生产者的数据的某种类型的交错,那么您可以从生产者到消费者。在

更好的方法(5)是让使用者在执行时打开一个名为管道的“控件”(/tmp/control.3456,3456是使用者的pid)。生产商首先使用“控制”管道建立一个通信通道。当一个生产者连接时,它将它的pid(如“1234”)发送到“control”管道上的使用者,后者告诉使用者创建一个命名管道,以便与生产者进行数据交换,例如“/tmp/data.1234”。然后,生产者关闭“控制”管道,打开“/tmp/data.1234”与消费者通信。每个使用者可以有自己的“控制”管道(使用使用者PID来区分不同使用者的管道),每个生产者都有自己的“数据”管道。。当producer finishes时,它应该清理它的数据管道,或者告诉使用者这样做。类似地,当用户完成时,它应该清理它的控制管道。在

这里的一个困难是防止多个生产者同时连接到单个消费者的控制管道。这里的“control”管道是一个共享资源,您需要在不同的生产者之间同步才能访问它。使用semaphores表示它或file locking。请参见posix_ipcpython模块。在

注意:我已经用一般的UNIX语义描述了上面的大部分内容,但是您真正需要的是能够创建守护进程,能够创建“命名”的管道/队列/任何东西,以便不相关的进程可以找到它们,以及能够在不相关的进程之间进行同步。您可以使用任何提供此类语义的python模块。在

有两种常见的方法来完成您的item#1(检测正在运行的进程),但是要使用它们,首先需要您稍微调整一下您的脑海中的画面,即这些后台进程是如何通过第一次调用程序启动的。在

第一个程序不是启动五个进程然后退出,而是检测到它是第一个启动的实例并且不是正在退出。它可以创建文件锁(防止应用程序多次运行的常用方法之一),也可以仅仅绑定到某个套接字(另一种常见方法)。任何一种方法都会在第二个实例中引发异常,然后它就会知道它不是第一个,并且可以重新将注意力集中在联系第一个实例上。在

如果您使用的是multiprocessing,那么您应该能够简单地使用Manager支持,这涉及到绑定到一个套接字来充当服务器。在

第一个程序启动进程,创建队列、代理等。它创建一个管理器来允许访问它们,可能允许remote access。在

随后的调用首先尝试在预定义的套接字上联系所述服务器/管理器(或使用其他技术来发现它所在的套接字)。而不是使用server_forever()调用它们connect(),并使用通常的multiprocessing机制进行通信。在

相关问题 更多 >