## Base type for contexts#classBaseContext(object):ProcessError=ProcessErrorBufferTooShort=BufferTooShortTimeoutError=TimeoutErrorAuthenticationError=AuthenticationErrorcurrent_process=staticmethod(process.current_process)active_children=staticmethod(process.active_children)defcpu_count(self):'''Returns the number of CPUs in the system'''num=os.cpu_count()ifnumisNone:raiseNotImplementedError('cannot determine number of cpus')else:returnnumdefManager(self):'''Returns a manager associated with a running server process The managers methods such as `Lock()`, `Condition()` and `Queue()` can be used to create shared objects. '''from.managersimportSyncManagerm=SyncManager(ctx=self.get_context())m.start()returnmdefPipe(self,duplex=True):'''Returns two connection object connected by a pipe'''from.connectionimportPipereturnPipe(duplex)defLock(self):'''Returns a non-recursive lock object'''from.synchronizeimportLockreturnLock(ctx=self.get_context())defRLock(self):'''Returns a recursive lock object'''from.synchronizeimportRLockreturnRLock(ctx=self.get_context())defCondition(self,lock=None):'''Returns a condition object'''from.synchronizeimportConditionreturnCondition(lock,ctx=self.get_context())defSemaphore(self,value=1):'''Returns a semaphore object'''from.synchronizeimportSemaphorereturnSemaphore(value,ctx=self.get_context())defBoundedSemaphore(self,value=1):'''Returns a bounded semaphore object'''from.synchronizeimportBoundedSemaphorereturnBoundedSemaphore(value,ctx=self.get_context())defEvent(self):'''Returns an event object'''from.synchronizeimportEventreturnEvent(ctx=self.get_context())defBarrier(self,parties,action=None,timeout=None):'''Returns a barrier object'''from.synchronizeimportBarrierreturnBarrier(parties,action,timeout,ctx=self.get_context())defQueue(self,maxsize=0):'''Returns a queue object'''from.queuesimportQueuereturnQueue(maxsize,ctx=self.get_context())defJoinableQueue(self,maxsize=0):'''Returns a queue object'''from.queuesimportJoinableQueuereturnJoinableQueue(maxsize,ctx=self.get_context())defSimpleQueue(self):'''Returns a queue object'''from.queuesimportSimpleQueuereturnSimpleQueue(ctx=self.get_context())defPool(self,processes=None,initializer=None,initargs=(),maxtasksperchild=None):'''Returns a process pool object'''from.poolimportPoolreturnPool(processes,initializer,initargs,maxtasksperchild,context=self.get_context())defRawValue(self,typecode_or_type,*args):'''Returns a shared object'''from.sharedctypesimportRawValuereturnRawValue(typecode_or_type,*args)defRawArray(self,typecode_or_type,size_or_initializer):'''Returns a shared array'''from.sharedctypesimportRawArrayreturnRawArray(typecode_or_type,size_or_initializer)defValue(self,typecode_or_type,*args,lock=True):'''Returns a synchronized shared object'''from.sharedctypesimportValuereturnValue(typecode_or_type,*args,lock=lock,ctx=self.get_context())defArray(self,typecode_or_type,size_or_initializer,*,lock=True):'''Returns a synchronized shared array'''from.sharedctypesimportArrayreturnArray(typecode_or_type,size_or_initializer,lock=lock,ctx=self.get_context())deffreeze_support(self):'''Check whether this is a fake forked process in a frozen executable. If so then run code specified by commandline and exit. '''ifsys.platform=='win32'andgetattr(sys,'frozen',False):from.spawnimportfreeze_supportfreeze_support()defget_logger(self):'''Return package logger -- if it does not already exist then it is created. '''from.utilimportget_loggerreturnget_logger()deflog_to_stderr(self,level=None):'''Turn on logging and add a handler which prints to stderr'''from.utilimportlog_to_stderrreturnlog_to_stderr(level)defallow_connection_pickling(self):'''Install support for sending connections and sockets between processes '''# This is undocumented. In previous versions of multiprocessing# its only effect was to make socket objects inheritable on Windows.from.importconnectiondefset_executable(self,executable):'''Sets the path to a python.exe or pythonw.exe binary used to run child processes instead of sys.executable when using the 'spawn' start method. Useful for people embedding Python. '''from.spawnimportset_executableset_executable(executable)defset_forkserver_preload(self,module_names):'''Set list of module names to try to load in forkserver process. This is really just a hint. '''from.forkserverimportset_forkserver_preloadset_forkserver_preload(module_names)defget_context(self,method=None):ifmethodisNone:returnselftry:ctx=_concrete_contexts[method]exceptKeyError:raiseValueError('cannot find context for %r'%method)ctx._check_available()returnctxdefget_start_method(self,allow_none=False):returnself._namedefset_start_method(self,method=None):raiseValueError('cannot set start method of concrete context')@propertydefreducer(self):'''Controls how objects will be reduced to a form that can be shared with other processes.'''returnglobals().get('reduction')@reducer.setterdefreducer(self,reduction):globals()['reduction']=reductiondef_check_available(self):pass## Type of default context -- underlying context can be set at most once#

classDefaultContext(BaseContext):Process=Processdef__init__(self,context):self._default_context=contextself._actual_context=Nonedefget_context(self,method=None):ifmethodisNone:ifself._actual_contextisNone:self._actual_context=self._default_contextreturnself._actual_contextelse:returnsuper().get_context(method)defset_start_method(self,method,force=False):ifself._actual_contextisnotNoneandnotforce:raiseRuntimeError('context has already been set')ifmethodisNoneandforce:self._actual_context=Nonereturnself._actual_context=self.get_context(method)defget_start_method(self,allow_none=False):ifself._actual_contextisNone:ifallow_none:returnNoneself._actual_context=self._default_contextreturnself._actual_context._namedefget_all_start_methods(self):ifsys.platform=='win32':return['spawn']else:ifreduction.HAVE_SEND_HANDLE:return['fork','spawn','forkserver']else:return['fork','spawn']DefaultContext.__all__=list(xforxindir(DefaultContext)ifx[0]!='_')## Context types for fixed start method#ifsys.platform!='win32':classForkProcess(process.BaseProcess):_start_method='fork'@staticmethoddef_Popen(process_obj):from.popen_forkimportPopenreturnPopen(process_obj)classSpawnProcess(process.BaseProcess):_start_method='spawn'@staticmethoddef_Popen(process_obj):from.popen_spawn_posiximportPopenreturnPopen(process_obj)classForkServerProcess(process.BaseProcess):_start_method='forkserver'@staticmethoddef_Popen(process_obj):from.popen_forkserverimportPopenreturnPopen(process_obj)classForkContext(BaseContext):_name='fork'Process=ForkProcessclassSpawnContext(BaseContext):_name='spawn'Process=SpawnProcessclassForkServerContext(BaseContext):_name='forkserver'Process=ForkServerProcessdef_check_available(self):ifnotreduction.HAVE_SEND_HANDLE:raiseValueError('forkserver start method not available')_concrete_contexts={'fork':ForkContext(),'spawn':SpawnContext(),'forkserver':ForkServerContext(),}_default_context=DefaultContext(_concrete_contexts['fork'])else:classSpawnProcess(process.BaseProcess):_start_method='spawn'@staticmethoddef_Popen(process_obj):from.popen_spawn_win32importPopenreturnPopen(process_obj)classSpawnContext(BaseContext):_name='spawn'Process=SpawnProcess_concrete_contexts={'spawn':SpawnContext(),}_default_context=DefaultContext(_concrete_contexts['spawn'])## Force the start method#def_force_start_method(method):_default_context._actual_context=_concrete_contexts[method]## Check that the current thread is spawning a child process#_tls=threading.local()defget_spawning_popen():returngetattr(_tls,'spawning_popen',None)defset_spawning_popen(popen):_tls.spawning_popen=popendefassert_spawning(obj):ifget_spawning_popen()isNone:raiseRuntimeError('%s objects should only be shared between processes'' through inheritance'%type(obj).__name__)