многопроцессорная обработка python — дочерний процесс блокирует родительский процесс

#python #multiprocessing

#python #многопроцессорная обработка

Вопрос:

Я пытаюсь изучить многопроцессорную обработку и создал пример, однако он ведет себя неожиданно. родительский процесс запускается, затем создается дочерний процесс, но ресурсы не возвращаются к родительскому процессу, пока дочерний процесс не будет завершен.

код:

 from multiprocessing import Process
import time

def f():
    newTime = time.time()   7
    while(time.time() < newTime):
        print("inside child process")
        time.sleep(int(5))

if __name__ == '__main__':
    bln = True
    while(True):
        newTime = time.time()   4
        while(time.time() < newTime):
            print("printing fillers")
            if(bln):
                p = Process(target=f)
                p.start()
                p.join()
                bln = False
  

Результат

«внутри дочернего процесса»

(подождите 5 секунд)

«внутри дочернего процесса»

«печать заполнителей»

«печать заполнителей»

[…]

Если я удалю ‘p.join ()’, тогда это сработает. Но, насколько я понимаю, p.join() должен сообщить программе дождаться завершения этого потока / процесса перед завершением программы. Может кто-нибудь сказать мне, почему это происходит?

Комментарии:

1. Не выполняйте объединение, пока не будете готовы дождаться завершения дочернего процесса. Я недостаточно хорошо понимаю замысел вашего кода, но обычно можно сохранить список процессов и присоединиться к ним вне while после завершения всей работы. Однако, похоже, что ваш код создаст огромное количество процессов за 4 секунды.

2. Нет, подождите, он выйдет из циклов после 1 дочернего процесса. Каковы ваши намерения в отношении кода? Это написано для создания одного дочернего процесса и ожидания его, и это то, что он делает.

3. @tdelaney то, что я хочу сделать в своей реальной программе, — это запустить процесс самостоятельно после выполнения определенного условия. Родителю все равно, что делает дочерний процесс или когда он заканчивается. Дочерний процесс завершит всю свою задачу, а затем завершит.

4. Я не уверен, как решить проблему. По умолчанию python будет ждать дочернего процесса при выходе родительского процесса независимо от конкретного соединения. Вы можете установить daemon=True при создании процесса… но я думаю, что дочерний процесс будет уничтожен при выходе родительского процесса. Возможно, я ошибаюсь в этом … в любом случае, возможно, вместо этого можно было бы запустить подпроцесс.

5. Спасибо @tdelaney, у меня действительно это работает, я просто хочу понять, почему наличие этого join() заставит его не работать. Я посмотрю на подпроцесс, может быть, он более подходит

Ответ №1:

Но, насколько я понимаю, p.join() должен сообщить программе дождаться завершения этого потока / процесса перед завершением программы.

Нет, он блокирует основной поток прямо тогда и там, пока поток / процесс не завершится. Делая это сразу после запуска процесса, вы не позволяете циклу продолжаться до тех пор, пока каждый процесс не завершится.

Было бы лучше собрать все Process объекты, которые вы создаете, в список, чтобы к ним можно было получить доступ после цикла их создания. Затем в новом цикле дождитесь их завершения только после того, как все они будут созданы и запущены.

 #for example
processes = []
for i in whatever:
    p = Process(target=foo)
    p.start()
    processes.append(p)
for p in processes:
    p.join()
  

Если вы хотите иметь возможность делать что-то в то же время (в ожидании join ), чаще всего используется еще один поток или процесс. Вы также можете выбрать только короткое время ожидания join , указав ему значение тайм-аута, и если процесс не завершится за это время, будет выдано исключение, которое вы можете перехватить с try помощью блока, и решите сделать что-то еще, прежде чем пытаться join снова.

Ответ №2:

p.join() предназначен не для завершения программы, а для ожидания завершения подпроцесса. Если вам нужно завершить программу, используйте что-то вроде sys.exit(0) или вызовите SystemExit(‘ваша причина здесь’)