Python: одновременное выполнение нескольких функций
Я пытаюсь запустить две функции одновременно в 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()
Ответы
Ответ 1
Вы делаете это правильно.:)
Попробуйте запустить этот глупый фрагмент кода:
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 func2" до "start func1".
Ответ 2
Это именно то, что мне нужно. Я знаю, что его не спрашивали, но я модифицировал код 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 для числа, затем напечатайте (ракета), и вы увидите, что он подсчитывает один за раз. Перейдите к номеру и остановите
Ответ 3
Это очень хороший пример @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()
Кроме того, проверьте эту тему: Когда вызывать .join() для процесса?
Ответ 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()
после " l.release()
"
Ответ 5
Это может быть сделано элегантно с 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])
Существует несколько преимуществ использования Ray по сравнению с многопроцессорным модулем. В частности, один и тот же код будет работать как на одной машине, так и на кластере машин. Для получения дополнительных преимуществ Рэй см. Этот пост.