我正在尝试在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()
答案 0 :(得分:42)
你正确地做到了。 :)
尝试运行这段愚蠢的代码:
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()
你会看到它打印'start func1'然后'start func2'然后在(非常)很长一段时间后你会看到函数结束。但它们确实会同时执行。
由于进程需要一段时间才能启动,因此您甚至可以在'start func1'之前看到'start func2'。
答案 1 :(得分:13)
这正是我所需要的。我知道它没有被问到,但我修改了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然后打印(火箭),你可以看到它一次计数一个。找到一个号码并停止
答案 2 :(得分:2)
这可以通过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的更多优点,请参见this related post。
答案 3 :(得分:1)
这是@Shashank的一个很好的例子。我只想说我必须在最后添加join
,否则这两个进程不会同时运行:
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()
此外,检查此线程: When to call .join() on a process?
答案 4 :(得分:0)
这里是另一个版本,如果需要运行动态进程列表。 如果您想尝试的话,我提供了两个shell脚本:
for i in {1..10}
do
echo "1... t.sh i:"$i
sleep 1
done
for i in {1..3}
do
echo "2.. t2.sh i:"$i
sleep 1
done
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()
”之后释放
答案 5 :(得分:0)
#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