代码之家  ›  专栏  ›  技术社区  ›  Imagist

检测流程是否已在运行并与其协作

  •  8
  • Imagist  · 技术社区  · 16 年前

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

    1. 生产者的数量各不相同。
    2. 消费者的数量是恒定的。

    我在用内置的 multiprocessing 模块,目前在Python 2.6.4中。,但最终打算转移到3.1.1。

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

    1. 用户启动 program.py operation -一个生产者,五个消费者。
    2. 用户启动 程序py操作 -一个生产者,五个消费者。
    3. 用户启动 程序py操作 -两个生产者,五个消费者。
    4. 操作完成-五个耗电元件正在运行。
    5. 用户启动 program.py stop 它完成了-没有进程运行。
    6. 用户启动 program.py start
    7. 程序py操作 -一名监制,五名消费者在跑步。
    8. 程序py停止 它完成了-没有进程运行。

    1. 检测到使用者进程正在运行。
    2. 从以前不相关的程序获得访问权限。
    3. 以跨平台的方式执行1和2。

    3 回复  |  直到 16 年前
        1
  •  2
  •   Peter Hansen    16 年前

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

    第一个程序不是启动五个进程然后退出,而是检测它是第一个启动并退出的实例

    multiprocessing ,您应该能够简单地使用 Manager 支持,包括绑定到套接字以充当服务器。

    remote access .

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

        2
  •  1
  •   James Branigan    16 年前

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

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

    Bonjour/zeroconf在跨平台上得到了很好的支持。您甚至可以配置Safari,向您显示本地网络上的zeroconf服务,以便您可以使用它为消费者调试服务广告。这种方法的一个优点是,您可以轻松地在不同于消费者的机器上运行生产者。

        3
  •  1
  •   Sudhanshu    16 年前

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

    如果我理解正确,对你的基本要求是:
    1.如果没有消费者,生产者应该能够产生消费者。

    3、生产者应该能够找到已有的消费者,并与他们进行沟通。

    5、一个以上的生产者应当能够与消费者沟通。

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

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

    (2) 生产者可以使用 named pipes . 看见 os.mkfifo() man page 属于 mkfifo()

    (3) 当用户进程开始运行时,您需要从用户进程中以众所周知的路径创建命名管道。生产商可以通过在同一位置查找这条知名管道来确定是否有消费者在运行。如果管道不存在,则没有消费者在运行,生产者可以生成这些管道。

    os.setuid() man page 设置ID()。

    (5) 这是一个棘手的问题。多个生产者可以使用同一命名管道与消费者通信,但您 cannot transfer more than "PIPE_BUF" amount of data 从生产者到消费者,如果您想可靠地确定是哪个生产者发送了数据,或者如果您想防止来自不同生产者的数据的某种交叉。

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

    这里的一个困难是防止多个生产商同时连接到单个消费者的控制管道。这里的“控制”管道是一个共享资源,您需要在不同的生产者之间同步以访问它。使用 semaphores 为了它或 file locking . 请参阅 python模块。

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