Python - 禁用多个py脚本实例并将其args传递给主实例

时间:2014-06-24 07:53:37

标签: python python-2.7

例如,我的py脚本已经有一个实例正在运行,当我用args触发另一个实例时,不是允许新实例运行,而是让它将args传递给主实例,或者让主实例知道args所以它可以做任何它需要做的args。这样的事情可能吗?

2 个答案:

答案 0 :(得分:0)

这是可能的,但不是微不足道的,因为这些过程是无关的。所以你必须设置:

  • 排除机制(文件锁应该可以在架构之间移植),以允许进程知道它是否是第一个 - 当新进程到达时服务器即将退出时要小心竞争条件......
  • 第一个进程打开一个侦听器 - 未使用端口上的套接字应该是可移植的
  • 您必须定义一个协议以允许您通过套接字进行通信
  • 当进程发现它不是第一个时,它会通过套接字与第一个进行联系并传递其参数

所以它可以工作,但这是很多工作......

如果您可以将您限制在特定架构(仅限Windows或仅使用Linux)并使用特定库,那么可能会有一些简单的解决方案,但这将是一项简单的工作。

答案 1 :(得分:0)

是的,这样的事情是可能的。我不确定是否可以可靠地检测应用程序的一个实例(进程)是否已在运行,但是一种可行的方法是为程序保留TCP端口。启动的第一个应用程序将在该端口上侦听,并像服务器一样工作。由于只有进程可以同时在同一端口上进行侦听,因此以下所有进程将无法创建侦听套接字,然后可以充当客户端。

您可以使用multiprocessing.connection来实现。以下是一个用于演示该概念的工作示例:

import multiprocessing.connection
import sys

SERVER_HOST = 'localhost'
SERVER_PORT = 6000

g_total = 0


def process_numbers(numbers):
    global g_total
    for number in numbers:
        g_total += number
        print('Adding number %d. Total is now %d.' % (number, g_total))


def server_main(listener, numbers):
    process_numbers(numbers)
    print('Starting server.')
    while True:
        client = listener.accept()
        numbers = list(client.recv())
        client.close()
        if not numbers:
            break
        process_numbers(numbers)


def client_main(numbers):
    client = multiprocessing.connection.Client((SERVER_HOST, SERVER_PORT), 'AF_INET')
    print('Starting client.')
    client.send(numbers)


def main():
    numbers = map(int, sys.argv[1:])
    try:
        listener = multiprocessing.connection.Listener((SERVER_HOST, SERVER_PORT), 'AF_INET')
    except OSError:
        client_main(numbers)
    else:
        server_main(listener, numbers)

if __name__ == '__main__':
    main()

假设您已将上述代码另存为main.py,则调用py main.py 1 2 3将显示以下输出:

Adding number 1. Total is now 1.
Adding number 2. Total is now 3.
Adding number 3. Total is now 6.
Starting server.

应用程序将继续运行。现在打开第二个终端并运行py main.py 4 5 6。该脚本只会打印:

Starting client.

但是,您的第一个应用程序(充当服务器)现在将打印:

Adding number 4. Total is now 10.
Adding number 5. Total is now 15.
Adding number 6. Total is now 21.

如果重复该命令,它将打印:

Adding number 4. Total is now 25.
Adding number 5. Total is now 30.
Adding number 6. Total is now 36.

,依此类推。您可以通过不带参数的客户端调用来退出服务器。

注意::此答案是为Python 3.7编写并经过测试的,因为Python 2.x已经失效。但是multiprocessing.connectionexists in Python 2.7,所以我认为代码也应该也可以在Python 2.7中运行(可能需要进行较小的修改)。