0 / 0 / 0
Регистрация: 22.02.2015
Сообщений: 45

Запуск подпроцессов из функции

17.05.2018, 18:14. Показов 7357. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пытаюсь сделать мультипроцессное приложение для ускорения работы моего скрипта, начал с простого примера:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os
from multiprocessing import Process
 
 
def procFunc(number):
    n = 1000000
    proc = os.getpid()
    for i in range(n):
        print("{0}: {1} - {2}".format(number, i, proc))
 
 
if __name__ == '__main__':
    p1 = Process(target=procFunc, args=(100,))
    p2 = Process(target=procFunc, args=(500,))
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()
Приведенный выше пример прекрасно работает, но я хочу запускать подпроцессы из функции, которую буду вызывать из некоторого места, поэтому пишу так:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os
from multiprocessing import Process
 
 
def procFunc(number):
    n = 1000000
    proc = os.getpid()
    for i in range(n):
        print("{0}: {1} - {2}".format(number, i, proc))
 
 
def main(): 
    p1 = Process(target=procFunc, args=(100,))
    p2 = Process(target=procFunc, args=(500,))
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()
а функцию main() вызываю из другого файла. В результате получаю ошибку:

Кликните здесь для просмотра всего текста
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 114, in _main
prepare(preparation_data)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 225, in prepare
_fixup_main_from_path(data['init_main_from_path'])
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 277, in _fixup_main_from_path
run_name="__mp_main__")
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\runpy.py", line 263, in run_path
pkg_name=pkg_name, script_name=fname)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\userweather\Desktop\Projects\P ython\003_Parallel\test.py", line 3, in <module>
mainn.main()
File "C:\Users\userweather\Desktop\Projects\P ython\003_Parallel\mainn.py", line 16, in main
p1.start()
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._ Popen(process_obj)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\popen_spawn_win32 .py", line 33, in __init__
prep_data = spawn.get_preparation_data(process_obj._ name)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 143, in get_preparation_data
_check_not_importing_main()
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 136, in _check_not_importing_main
is not going to be frozen to produce an executable.''')
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.

This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:

if __name__ == '__main__':
freeze_support()
...

The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 114, in _main
prepare(preparation_data)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 225, in prepare
_fixup_main_from_path(data['init_main_from_path'])
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 277, in _fixup_main_from_path
run_name="__mp_main__")
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\runpy.py", line 263, in run_path
pkg_name=pkg_name, script_name=fname)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\userweather\Desktop\Projects\P ython\003_Parallel\test.py", line 3, in <module>
mainn.main()
File "C:\Users\userweather\Desktop\Projects\P ython\003_Parallel\mainn.py", line 16, in main
p1.start()
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._ Popen(process_obj)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\popen_spawn_win32 .py", line 33, in __init__
prep_data = spawn.get_preparation_data(process_obj._ name)
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 143, in get_preparation_data
_check_not_importing_main()
File "C:\Users\userweather\AppData\Local\Prog rams\Python\Python36-32\lib\multiprocessing\spawn.py", line 136, in _check_not_importing_main
is not going to be frozen to produce an executable.''')
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.

This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:

if __name__ == '__main__':
freeze_support()
...

The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.


Скажите, как реализовать задуманное, чтобы вызов подпроцессов осуществлялся в рамках функции (или даже метода класса).
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.05.2018, 18:14
Ответы с готовыми решениями:

Как запретить повторный запуск функции или оюойти условие в данной функции
Приветствую рбята! Второй день голову ломаю. Пытаюсь создать скрипт, который бы при скролинге на определенном блоке прекращался на...

Запуск функции
Здравствуйте уважаемые форумчане, очень нужна ваша помощь! Есть функция void F3(double *p, double *q) { int i,n; for...

Запуск функции по таймеру
Здравствуйте, в консольном приложении у меня есть две функции, мне нужно запускать их поочередно в цикле, каждую через определенное время в...

4
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
17.05.2018, 18:31
В ошибке все написано - на windows при мультипроцессинге нужно использовать точку входа. Привыкайте писать везде, даже если это кажется вам странным:
Python
1
2
3
if __name__ == '__main__':
   # вызов функции
    freeze_support()
1
0 / 0 / 0
Регистрация: 22.02.2015
Сообщений: 45
17.05.2018, 23:43  [ТС]
Garry Galler, т.е. правильно я понимаю, что внутри функции нельзя создать дочерние процессы, и, как следствие, нельзя поместить мультипроцессинг в логику какого-нибудь класса, чтобы человек, который этот класс использует, ни о каких мультипроцессах не задумывался
0
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
18.05.2018, 00:21
Можно. Просто есть простая идиома: используешь код с мультипроцессингом - изволь запускать его из точки входа if __name__ == "__main__"
Это во всех документациях по мультипроцессам написано.
Но обязательно это только на windows - в linux процессы форкаются проще, поэтому интерпретатору не требуется "водораздел" между кодом и его запуском.

Python
1
2
3
4
5
6
# импортирую код который запускает много процессов
from multiprocessing_test2 import main
 
if __name__ == "__main__":
    # запускаю его после точки входа и никаких проблем.
    main()
Добавлено через 2 минуты
P.S. Собственно, сама точка входа: if __name__ == "__main__" это обычный стиль программирования на python: сначала код, затем его вызов в точке входа в скрипт.
Это принято писать всегда и везде - поэтому у большинства никаких проблем с мультипроцессингом не возникает.

Добавлено через 13 минут
P.P.S. В любом случае интерпретатор скажет, что делать в traceback'е ошибки:
Была предпринята попытка начать новый процесс до того как
текущий процесс завершил этап начальной загрузки.
Вероятно, это означает, что вы не используете fork для запуска своих
дочерних процессов, или вы забыли использовать правильную идиому
в основном модуле
1
0 / 0 / 0
Регистрация: 22.02.2015
Сообщений: 45
18.05.2018, 15:04  [ТС]
Garry Galler, Спасибо, теперь все работает. Хочу задать еще один вопрос, у меня есть скрипт, где в цикле некоторое количество раз N вызывается функция calc(), набор аргументов при вызове функции calc() каждый раз уникальный. Хотелось бы сделать список задач, каждый элемент которого - аргументы для очередного вызова функции calc(), и чтобы эти задачи выполнились некоторым количеством процессов n, так, чтобы когда какой-нибудь из n процессов завершится - тут же запускался бы другой процесс с новым заданием из списка задач и так до тех пор, пока все N задач не будут просчитаны.

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

Скажите, как решить эту задачу, избежав простоя процессорной мощности?
Прошу прощение за подобные вопросы, это мое первое мультипроцессное приложение.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.05.2018, 15:04
Помогаю со студенческими работами здесь

Запуск функции в цикле
Есть некая функция private void one() { two() } private void two() { three() }

Запуск функции по условию
Как сделать в javascript так, чтобы при каком то условии не срабатывала функция. Заранее спасибо!!

Запуск файла и функции
Есть код, как запустить его и вызвать функцию в GNU CLISP 2.49. Как всё это прописать чтобы работало? и будет ли этот код...

Запуск отдельной функции
как можно запустить отдельно функцию по типу. В обычном коде работает а в WF C# чот не реагирует ни как ... Void blabla(){ ...

Многократный запуск функции
Почитал похожие темы про Timers, но мало что понял. Мне необходимо запускать функцию типа &quot;void (string z, string x)&quot; через...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru