37,744
社区成员




#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os, time
from multiprocessing import *
def test(x):
print current_process().pid, x
time.sleep(1)
if __name__ == "__main__":
print "main:", os.getpid()
p = Pool(5)
p.map(test, range(13))
$ ./test.py
main: 1208
1209 0
1210 1
1211 2
1212 3
1213 4
1210 5
1209 6
1212 7
1211 8
1213 9
1209 10
1210 11
1212 12
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os, time
from multiprocessing import *
def test(x):
print current_process().pid, x
time.sleep(1)
if __name__ == "__main__":
print "main:", os.getpid()
p = Process(target = test, args = [100])
p.start()
p.join()
$ ./test.py
main: 1229
1230 100
class Process(object):
'''
Process objects represent activity that is run in a separate process
The class is analagous to `threading.Thread`
'''
_Popen = None
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
...
self._parent_pid = os.getpid()
self._popen = None
self._target = target
self._args = tuple(args)
self._kwargs = dict(kwargs)
...
def start(self):
...
if self._Popen is not None:
Popen = self._Popen
else:
from .forking import Popen
self._popen = Popen(self)
_current_process._children.add(self)
class Popen(object):
def __init__(self, process_obj):
...
self.pid = os.fork()
if self.pid == 0:
...
code = process_obj._bootstrap()
sys.stdout.flush()
sys.stderr.flush()
os._exit(code)
class Process(object):
def _bootstrap(self):
from . import util
global _current_process
try:
self._children = set()
self._counter = itertools.count(1)
try:
sys.stdin.close()
sys.stdin = open(os.devnull)
except (OSError, ValueError):
pass
_current_process = self # 重置了 _current_process !
util._finalizer_registry.clear()
util._run_after_forkers()
util.info('child process calling self.run()')
try:
self.run()
exitcode = 0
finally:
util._exit_function()
except SystemExit, e:
if not e.args:
exitcode = 1
elif type(e.args[0]) is int:
exitcode = e.args[0]
else:
sys.stderr.write(e.args[0] + '\n')
sys.stderr.flush()
exitcode = 1
except:
exitcode = 1
import traceback
sys.stderr.write('Process %s:\n' % self.name)
sys.stderr.flush()
traceback.print_exc()
util.info('process exiting with exitcode %d' % exitcode)
return exitcode
class Process(object):
def run(self):
if self._target:
self._target(*self._args, **self._kwargs)
class Process(object):
def start(self):
...
if self._Popen is not None:
Popen = self._Popen
else:
from .forking import Popen
self._popen = Popen(self)
_current_process._children.add(self)
class _MainProcess(Process):
def __init__(self):
self._identity = ()
self._daemonic = False
self._name = 'MainProcess'
self._parent_pid = None
self._popen = None
self._counter = itertools.count(1)
self._children = set()
self._authkey = AuthenticationString(os.urandom(32))
self._tempdir = None
_current_process = _MainProcess()
del _MainProcess
from multiprocessing.util import SUBDEBUG, SUBWARNING
from multiprocessing.process import current_process, active_children
def _exit_function():
global _exiting
info('process shutting down')
debug('running all "atexit" finalizers with priority >= 0')
_run_finalizers(0)
for p in active_children():
if p._daemonic:
info('calling terminate() for daemon %s', p.name)
p._popen.terminate()
for p in active_children():
info('calling join() for process %s', p.name)
p.join()
debug('running the remaining "atexit" finalizers')
_run_finalizers()
atexit.register(_exit_function)
def current_process():
'''Return process object representing the current process'''
return _current_process
def active_children():
'''Return list of process objects corresponding to live child processes'''
_cleanup()
return list(_current_process._children)
class Process(object):
def join(self, timeout=None):
...
res = self._popen.wait(timeout)
if res is not None:
_current_process._children.discard(self)
class Popen(object):
def wait(self, timeout=None):
if timeout is None:
return self.poll(0)
...
while 1:
res = self.poll()
...
return res
def poll(self, flag=os.WNOHANG):
if self.returncode is None:
pid, sts = os.waitpid(self.pid, flag)
if pid == self.pid:
if os.WIFSIGNALED(sts):
self.returncode = -os.WTERMSIG(sts)
else:
assert os.WIFEXITED(sts)
self.returncode = os.WEXITSTATUS(sts)
return self.returncode
def terminate(self):
if self.returncode is None:
try:
os.kill(self.pid, signal.SIGTERM)
except OSError, e:
if self.wait(timeout=0.1) is None:
raise