同时执行多个功能

问题描述 投票:0回答:6

我正在尝试在 Python 中同时运行两个函数。我尝试了以下使用

multiprocessing
的代码,但是当我执行代码时,第二个函数仅在第一个函数完成后才启动。

from multiprocessing import Process
def func1:
     #does something

def func2:
     #does something

if __name__=='__main__':
     p1 = Process(target = func1)
     p1.start()
     p2 = Process(target = func2)
     p2.start()
python concurrency multitasking
6个回答
71
投票

你做得正确。 :)

尝试运行这段愚蠢的代码:

from multiprocessing import Process
import sys

rocket = 0

def func1():
    global rocket
    print('start func1')
    while rocket < sys.maxsize:
        rocket += 1
    print('end func1')

def func2():
    global rocket
    print('start func2')
    while rocket < sys.maxsize:
        rocket += 1
    print('end func2')

if __name__=='__main__':
    p1 = Process(target=func1)
    p1.start()
    p2 = Process(target=func2)
    p2.start()

您将看到它打印“start func1”,然后打印“start func2”,然后经过(非常)长时间,您终于会看到函数结束。但他们确实会同时执行。

由于进程需要一段时间才能启动,您甚至可能会在“start func1”之前看到“start func2”。


34
投票
这正是我所需要的。我知道没有人问,但我修改了 shashank 的代码以适合其他人寻找的 Python 3 :)

from multiprocessing import Process import sys rocket = 0 def func1(): global rocket print ('start func1') while rocket < sys.maxsize: rocket += 1 print ('end func1') def func2(): global rocket print ('start func2') while rocket < sys.maxsize: rocket += 1 print ('end func2') if __name__=='__main__': p1 = Process(target=func1) p1.start() p2 = Process(target=func2) p2.start()

用 sys.maxsize 替换一个数字,然后 print(rocket),你可以看到它一次加一。到达一个号码并停下来


11
投票
这可以通过

Ray 优雅地完成,该系统允许您轻松并行化和分发 Python 代码。

要并行化您的示例,您需要使用

@ray.remote decorator

 定义函数,然后使用 
.remote
 调用它们。

import ray ray.init() # Define functions you want to execute in parallel using # the ray.remote decorator. @ray.remote def func1(): #does something @ray.remote def func2(): #does something # Execute func1 and func2 in parallel. ray.get([func1.remote(), func2.remote()])

如果

func1()

func2()
返回结果,则需要重写代码如下:

ret_id1 = func1.remote() ret_id2 = func1.remote() ret1, ret2 = ray.get([ret_id1, ret_id2])

multiprocessing 模块相比,使用 Ray 有许多优点。特别是,“相同的代码”可以在单台机器上运行,也可以在机器集群上运行。有关 Ray 的更多优点,请参阅此相关帖子

这是@Shashank 的一个非常好的例子。我只想说我必须在最后添加

8
投票
,否则两个进程不会同时运行:

from multiprocessing import Process
import sys

rocket = 0

def func1():
    global rocket
    print 'start func1'
    while rocket < sys.maxint:
        rocket += 1
    print 'end func1'

def func2():
    global rocket
    print 'start func2'
    while rocket < sys.maxint:
        rocket += 1
    print 'end func2'

if __name__=='__main__':
    p1 = Process(target = func1)
    p1.start()
    p2 = Process(target = func2)
    p2.start()
    # This is where I had to add the join() function.
    p1.join()
    p2.join()

此外,请查看此线程:
何时在进程上调用 .join()?

如果需要运行动态进程列表,这是另一个版本。 我提供了两个 shell 脚本,如果你想尝试的话:

4
投票
t1.sh

for i in {1..10} do echo "1... t.sh i:"$i sleep 1 done

t2.sh

for i in {1..3} do echo "2.. t2.sh i:"$i sleep 1 done

np.py

import os from multiprocessing import Process, Lock def f(l, cmd): os.system(cmd) if __name__ == '__main__': lock = Lock() for cmd in ['sh t1.sh', 'sh t2.sh']: Process(target=f, args=(lock, cmd)).start()

输出

1... t.sh i:1 2.. t2.sh i:1 1... t.sh i:2 2.. t2.sh i:2 1... t.sh i:3 2.. t2.sh i:3 1... t.sh i:4 1... t.sh i:5 1... t.sh i:6 1... t.sh i:7 1... t.sh i:8 1... t.sh i:9 1... t.sh i:10

留下的“锁”可以在任务“
l.acquire()
”之前获取并在“

l.release()

”之后释放

#Try by using threads instead of multiprocessing #from multiprocessing import Process #import sys import time import threading import random rocket = 0 def func1(): global rocket print('start func1') while rocket < 100: print("Im in func1") rocket += 1 value = "Im global var "+str(rocket)+" from fun1" print(value) print ('end func1') def func2(): global rocket print ('start func2') while rocket < 100: print("Im in func2") rocket += 1 value = "Im global var " + str(rocket) + " from fun2" print(value) print ('end func2') if __name__=='__main__': p1 = threading.Thread(target=func1) p2 = threading.Thread(target=func2) p1.start();p2.start() #Hope it works

0
投票

© www.soinside.com 2019 - 2024. All rights reserved.