多线程不同脚本

1 投票
2 回答
4634 浏览
提问于 2025-04-16 12:23

我有几个用Python写的脚本。
我想让它们同时运行。

当脚本A启动时,我希望脚本B、C和D也能一起启动。
在A运行完后,我想让A2运行。
在B运行完后,我想让B2运行,然后是B3。
C和D没有后续的脚本。

我已经确认这些脚本之间是相互独立的。
我打算用"exec"来启动它们,并希望在Linux和Windows上都能使用这个“启动器”。

我还有其他的多线程脚本,主要是用五个线程执行一个过程A。
这让我感到困惑,因为所有的过程都不同,但可以同时启动和运行。

2 个回答

0

所以不一定非得用Python启动器吗?我以前做系统管理的时候,写过一个Perl脚本,使用了POE框架来运行一些脚本,控制并发量。效果很好。比如说,当我们需要在一千个用户账户或者几百个数据库上运行脚本时,就可以限制同时运行的任务数量,比如在一个4核的机器上限制为4个任务,在一个16核的服务器上限制为16个,或者你想要的任何数量。POE确实使用了fork()来创建子进程,但在Windows机器上,使用cygwin也能很好地运行,顺便提一下。

不久前我在找一个Python的事件框架。今天再看,发现了Twisted,还有一些帖子说它的运行速度甚至比POE还快,但也许Twisted主要是用于网络客户端/服务器?POE非常灵活。如果你不习惯事件驱动的编程,刚开始会有点难,但即使你习惯了,事件的处理也比线程简单多了。(也许对你的需求来说有点过于复杂?这么多年过去了,我还是觉得没有一个简单的工具来控制多核机器的任务处理速度。)

2

好的,我还不太确定你的问题到底出在哪里,但这是我解决问题的方法:

#Main.py
from multiprocessing import Process
import ScriptA
# import all other scripts as well

def handle_script_a(*args):
    print("Call one or several functions from Script A or calculate some stuff beforehand")
    ScriptA.foo(*args)

if __name__ == '__main__':
    p = Process(target=handle_script_a, args=("Either so", ))
    p1 = Process(target=ScriptA.foo, args=("or so", ))
    p.start()
    p1.start()
    p.join()
    p1.join()

# ScriptA.py:
def foo(*args):
    print("Function foo called with args:")
    for arg in args:
        print(arg)

你可以直接调用一个函数,或者如果想在一个过程中调用多个函数,可以用一个小的包装器来实现。这样就没有平台相关的代码,也不用写那些复杂的执行命令,你可以用任何你喜欢的方式轻松创建或加入进程。

这里有一个关于进程间通信的队列的小例子——基本上是从Python的API中借来的,不过还不错;)

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()

创建队列并给它一个或多个进程。注意,get() 方法会阻塞,如果你想要非阻塞的,可以使用 get_nowait(),或者指定一个超时时间作为第二个参数。如果你想要共享对象,可以使用 multiprocessing.Array 或 multiprocessing.Value,具体信息可以查看文档 文档链接。如果你还有关于进程间通信的问题,可以另开一个问题——这是一个非常庞大的主题。

撰写回答