내가 만난 문제는 모듈간에 전역을 가져 오려고 할 때 ProcessPool () 줄이 여러 번 평가되는 것입니다.
globals.py
from processing import Manager, Lock
from pathos.multiprocessing import ProcessPool
from pathos.threading import ThreadPool
class SingletonMeta(type):
def __new__(cls, name, bases, dict):
dict['__deepcopy__'] = dict['__copy__'] = lambda self, *args: self
return super(SingletonMeta, cls).__new__(cls, name, bases, dict)
def __init__(cls, name, bases, dict):
super(SingletonMeta, cls).__init__(name, bases, dict)
cls.instance = None
def __call__(cls,*args,**kw):
if cls.instance is None:
cls.instance = super(SingletonMeta, cls).__call__(*args, **kw)
return cls.instance
def __deepcopy__(self, item):
return item.__class__.instance
class Globals(object):
__metaclass__ = SingletonMeta
"""
This class is a workaround to the bug: AssertionError: daemonic processes are not allowed to have children
The root cause is that importing this file from different modules causes this file to be reevalutated each time,
thus ProcessPool() gets reexecuted inside that child thread, thus causing the daemonic processes bug
"""
def __init__(self):
print "%s::__init__()" % (self.__class__.__name__)
self.shared_manager = Manager()
self.shared_process_pool = ProcessPool()
self.shared_thread_pool = ThreadPool()
self.shared_lock = Lock()
그런 다음 코드의 다른 곳에서 안전하게 가져옵니다.
from globals import Globals
Globals().shared_manager
Globals().shared_process_pool
Globals().shared_thread_pool
Globals().shared_lock
pathos.multiprocessing
여기에 좀 더 확장 된 래퍼 클래스를 작성했습니다 .
참고로, 사용 사례에 성능 최적화로 비동기 다중 프로세스 맵만 필요한 경우 joblib는 모든 프로세스 풀을 백그라운드에서 관리하고 다음과 같은 매우 간단한 구문을 허용합니다.
squares = Parallel(-1)( delayed(lambda num: num**2)(x) for x in range(100) )
I want a pool to be able to call a function that has another pool inside
과 작업자가 데몬 화된다는 사실을 어떻게 방해하는지 이해하지 못합니다 .