Итак, я делаю этот проект, в котором выполняются следующие шаги (обязательно такие, какие они есть):
- Программа алгоритма оптимизации (пакет O) вызывает скрипт анализа самолета в качестве подпроцесса;
- Сценарий анализа летательного аппарата (сценарий S) вызывает пакет аэродинамики;
- Пакет анализа летательного аппарата (назовем его пакетом P) создает несколько многопроцессорных экземпляров класса
Process
для распараллеливания тяжелых задач.
На Linux это работает без каких-либо проблем.
На Windows, однако, пакету P требуется защита, не позволяющая дочерним процессам рекурсивно повторно импортировать свой сценарий отца S (как в python многопроцессорная обработка на Windows), что приводит к бесконечно повторяющемуся выполнению задачи.
Нетрудно реализовать его, добавив защиту к сценарию S:
if __name__=='__main__':
#do stuff, call methods from package P
Я не хотел, чтобы мои пользователи использовали этот сторож при каждом обращении к пакету, поэтому вместо этого я добавил сторож к пакету P. Он реализован в виде флага, как в (имена, отредактированные для простоты, пакет имеет более 5000 строк):
class FirstClass:
#first method in package P to be executed in script S is FirstClass.__init__
def __init__(self):
self.ischild=(multiprocessing.current_process().name != 'MainProcess')
def some_other_method(self):
if not self.ischild:
do_stuff_that_the_package_should_do()
Таким образом, по сути, функции и методы пакета P запускаются, только если установлен флаг ischild
установлен в False в первом классе, созданном сценарием S.
Он работает, когда сценарий S вызывается из командной строки, и останавливает сценарий S от выполнения каких-либо действий в дочернем процессе, поскольку он реимпортируется - следовательно, останавливает оба избыточные задачи и создание рекурсивного подпроцесса.
Когда я пытаюсь настроить пакет оптимизации O для запуска сценария S в качестве подпроцесса, однако, эта защита перестает работать, поскольку сценарий S больше не является основным процессом. Флаг ischild
, таким образом, устанавливается в True, даже когда скрипт S запускается впервые пакетом O, потому что multiprocessing.current_process().name
больше не равен 'MainProcess'
, даже если вызов не рекурсивный.
Есть ли какой-нибудь другой способ, которым я могу реализовать Guard для пакета P, чтобы остановить его рекурсивные вызовы основного процесса, который работал бы, даже если скрипт S не является основным процессом?
Это было бы было бы хорошо, если бы я мог точно определить, какой пакет / скрипт вызвал процесс, с помощью чего-то вроде:
if multiprocessing.father()=='package_P':
ischild=True #stops execution of function do_stuff_the_package_should_do() when the call is recursive
, чтобы не возникало никаких проблем, когда вызывающий процесс не является ни основным процессом (как это было бы, если бы сценарий S является подпроцессом другого сценария или пакета), а также дочерним процессом из пакета P (рекурсивный вызов).