Home | History | Annotate | Download | only in multiprocessing
      1 #
      2 # Package analogous to 'threading.py' but using processes
      3 #
      4 # multiprocessing/__init__.py
      5 #
      6 # This package is intended to duplicate the functionality (and much of
      7 # the API) of threading.py but uses processes instead of threads.  A
      8 # subpackage 'multiprocessing.dummy' has the same API but is a simple
      9 # wrapper for 'threading'.
     10 #
     11 # Try calling `multiprocessing.doc.main()` to read the html
     12 # documentation in a webbrowser.
     13 #
     14 #
     15 # Copyright (c) 2006-2008, R Oudkerk
     16 # All rights reserved.
     17 #
     18 # Redistribution and use in source and binary forms, with or without
     19 # modification, are permitted provided that the following conditions
     20 # are met:
     21 #
     22 # 1. Redistributions of source code must retain the above copyright
     23 #    notice, this list of conditions and the following disclaimer.
     24 # 2. Redistributions in binary form must reproduce the above copyright
     25 #    notice, this list of conditions and the following disclaimer in the
     26 #    documentation and/or other materials provided with the distribution.
     27 # 3. Neither the name of author nor the names of any contributors may be
     28 #    used to endorse or promote products derived from this software
     29 #    without specific prior written permission.
     30 #
     31 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
     32 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     33 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     34 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     35 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     39 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     40 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     41 # SUCH DAMAGE.
     42 #
     43 
     44 __version__ = '0.70a1'
     45 
     46 __all__ = [
     47     'Process', 'current_process', 'active_children', 'freeze_support',
     48     'Manager', 'Pipe', 'cpu_count', 'log_to_stderr', 'get_logger',
     49     'allow_connection_pickling', 'BufferTooShort', 'TimeoutError',
     50     'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
     51     'Event', 'Queue', 'JoinableQueue', 'Pool', 'Value', 'Array',
     52     'RawValue', 'RawArray', 'SUBDEBUG', 'SUBWARNING',
     53     ]
     54 
     55 __author__ = 'R. Oudkerk (r.m.oudkerk (at] gmail.com)'
     56 
     57 #
     58 # Imports
     59 #
     60 
     61 import os
     62 import sys
     63 
     64 from multiprocessing.process import Process, current_process, active_children
     65 from multiprocessing.util import SUBDEBUG, SUBWARNING
     66 
     67 #
     68 # Exceptions
     69 #
     70 
     71 class ProcessError(Exception):
     72     pass
     73 
     74 class BufferTooShort(ProcessError):
     75     pass
     76 
     77 class TimeoutError(ProcessError):
     78     pass
     79 
     80 class AuthenticationError(ProcessError):
     81     pass
     82 
     83 # This is down here because _multiprocessing uses BufferTooShort
     84 import _multiprocessing
     85 
     86 #
     87 # Definitions not depending on native semaphores
     88 #
     89 
     90 def Manager():
     91     '''
     92     Returns a manager associated with a running server process
     93 
     94     The managers methods such as `Lock()`, `Condition()` and `Queue()`
     95     can be used to create shared objects.
     96     '''
     97     from multiprocessing.managers import SyncManager
     98     m = SyncManager()
     99     m.start()
    100     return m
    101 
    102 def Pipe(duplex=True):
    103     '''
    104     Returns two connection object connected by a pipe
    105     '''
    106     from multiprocessing.connection import Pipe
    107     return Pipe(duplex)
    108 
    109 def cpu_count():
    110     '''
    111     Returns the number of CPUs in the system
    112     '''
    113     if sys.platform == 'win32':
    114         try:
    115             num = int(os.environ['NUMBER_OF_PROCESSORS'])
    116         except (ValueError, KeyError):
    117             num = 0
    118     elif 'bsd' in sys.platform or sys.platform == 'darwin':
    119         comm = '/sbin/sysctl -n hw.ncpu'
    120         if sys.platform == 'darwin':
    121             comm = '/usr' + comm
    122         try:
    123             with os.popen(comm) as p:
    124                 num = int(p.read())
    125         except ValueError:
    126             num = 0
    127     else:
    128         try:
    129             num = os.sysconf('SC_NPROCESSORS_ONLN')
    130         except (ValueError, OSError, AttributeError):
    131             num = 0
    132 
    133     if num >= 1:
    134         return num
    135     else:
    136         raise NotImplementedError('cannot determine number of cpus')
    137 
    138 def freeze_support():
    139     '''
    140     Check whether this is a fake forked process in a frozen executable.
    141     If so then run code specified by commandline and exit.
    142     '''
    143     if sys.platform == 'win32' and getattr(sys, 'frozen', False):
    144         from multiprocessing.forking import freeze_support
    145         freeze_support()
    146 
    147 def get_logger():
    148     '''
    149     Return package logger -- if it does not already exist then it is created
    150     '''
    151     from multiprocessing.util import get_logger
    152     return get_logger()
    153 
    154 def log_to_stderr(level=None):
    155     '''
    156     Turn on logging and add a handler which prints to stderr
    157     '''
    158     from multiprocessing.util import log_to_stderr
    159     return log_to_stderr(level)
    160 
    161 def allow_connection_pickling():
    162     '''
    163     Install support for sending connections and sockets between processes
    164     '''
    165     from multiprocessing import reduction
    166 
    167 #
    168 # Definitions depending on native semaphores
    169 #
    170 
    171 def Lock():
    172     '''
    173     Returns a non-recursive lock object
    174     '''
    175     from multiprocessing.synchronize import Lock
    176     return Lock()
    177 
    178 def RLock():
    179     '''
    180     Returns a recursive lock object
    181     '''
    182     from multiprocessing.synchronize import RLock
    183     return RLock()
    184 
    185 def Condition(lock=None):
    186     '''
    187     Returns a condition object
    188     '''
    189     from multiprocessing.synchronize import Condition
    190     return Condition(lock)
    191 
    192 def Semaphore(value=1):
    193     '''
    194     Returns a semaphore object
    195     '''
    196     from multiprocessing.synchronize import Semaphore
    197     return Semaphore(value)
    198 
    199 def BoundedSemaphore(value=1):
    200     '''
    201     Returns a bounded semaphore object
    202     '''
    203     from multiprocessing.synchronize import BoundedSemaphore
    204     return BoundedSemaphore(value)
    205 
    206 def Event():
    207     '''
    208     Returns an event object
    209     '''
    210     from multiprocessing.synchronize import Event
    211     return Event()
    212 
    213 def Queue(maxsize=0):
    214     '''
    215     Returns a queue object
    216     '''
    217     from multiprocessing.queues import Queue
    218     return Queue(maxsize)
    219 
    220 def JoinableQueue(maxsize=0):
    221     '''
    222     Returns a queue object
    223     '''
    224     from multiprocessing.queues import JoinableQueue
    225     return JoinableQueue(maxsize)
    226 
    227 def Pool(processes=None, initializer=None, initargs=(), maxtasksperchild=None):
    228     '''
    229     Returns a process pool object
    230     '''
    231     from multiprocessing.pool import Pool
    232     return Pool(processes, initializer, initargs, maxtasksperchild)
    233 
    234 def RawValue(typecode_or_type, *args):
    235     '''
    236     Returns a shared object
    237     '''
    238     from multiprocessing.sharedctypes import RawValue
    239     return RawValue(typecode_or_type, *args)
    240 
    241 def RawArray(typecode_or_type, size_or_initializer):
    242     '''
    243     Returns a shared array
    244     '''
    245     from multiprocessing.sharedctypes import RawArray
    246     return RawArray(typecode_or_type, size_or_initializer)
    247 
    248 def Value(typecode_or_type, *args, **kwds):
    249     '''
    250     Returns a synchronized shared object
    251     '''
    252     from multiprocessing.sharedctypes import Value
    253     return Value(typecode_or_type, *args, **kwds)
    254 
    255 def Array(typecode_or_type, size_or_initializer, **kwds):
    256     '''
    257     Returns a synchronized shared array
    258     '''
    259     from multiprocessing.sharedctypes import Array
    260     return Array(typecode_or_type, size_or_initializer, **kwds)
    261 
    262 #
    263 #
    264 #
    265 
    266 if sys.platform == 'win32':
    267 
    268     def set_executable(executable):
    269         '''
    270         Sets the path to a python.exe or pythonw.exe binary used to run
    271         child processes on Windows instead of sys.executable.
    272         Useful for people embedding Python.
    273         '''
    274         from multiprocessing.forking import set_executable
    275         set_executable(executable)
    276 
    277     __all__ += ['set_executable']
    278