def serve_forever(self, poll_interval=0.1):
"""Fork the current process and wait for all children to finish."""
if self.prefork is None or self.prefork <= 1:
return super(_SporkMixIn, self).serve_forever(
poll_interval=poll_interval)
pids = []
for dummy in range(self.prefork):
pid = os.fork()
if not pid:
super(_SporkMixIn, self).serve_forever(
poll_interval=poll_interval)
os._exit(0)
else:
self.log.info("Forked worker %s", pid)
pids.append(pid)
self.pids = pids
for pid in self.pids:
_eintr_retry(os.waitpid, pid, 0)
python类waitpid()的实例源码
def waitfinish(self, waiter=os.waitpid):
pid, systemstatus = waiter(self.pid, 0)
if systemstatus:
if os.WIFSIGNALED(systemstatus):
exitstatus = os.WTERMSIG(systemstatus) + 128
else:
exitstatus = os.WEXITSTATUS(systemstatus)
else:
exitstatus = 0
signal = systemstatus & 0x7f
if not exitstatus and not signal:
retval = self.RETVAL.open('rb')
try:
retval_data = retval.read()
finally:
retval.close()
retval = marshal.loads(retval_data)
else:
retval = None
stdout = self.STDOUT.read()
stderr = self.STDERR.read()
self._removetemp()
return Result(exitstatus, signal, retval, stdout, stderr)
def stop(self):
self._log.debug("stop()")
if self.get_commandAlive() == True:
for sig, timeout in self.STOP_SIGNALS:
try:
os.kill(self._pid, sig)
except OSError:
self._pid = None
return
if timeout != None:
giveup_time = time.time() + timeout
while os.waitpid(self._pid, os.WNOHANG) == (0,0):
time.sleep(0.1)
if time.time() > giveup_time:
break
else:
# Wait until there is a response
os.waitpid(self._pid, 0)
self._pid = None
######################################
# Implement specific property setters/getters
def get_commandAlive(self):
if self._pid != None:
try:
os.kill(self._pid, 0)
if os.waitpid(self._pid, os.WNOHANG) == (0,0):
return True
else:
return False
except OSError:
pass
return False
def stop(self):
self._log.debug("stop()")
if self.get_commandAlive() == True:
for sig, timeout in self.STOP_SIGNALS:
try:
os.kill(self._pid, sig)
except OSError:
self._pid = None
return
if timeout != None:
giveup_time = time.time() + timeout
while os.waitpid(self._pid, os.WNOHANG) == (0,0):
time.sleep(0.1)
if time.time() > giveup_time:
break
else:
# Wait until there is a response
os.waitpid(self._pid, 0)
self._pid = None
######################################
# Implement specific property setters/getters
def stop(self):
self._log.debug("%s.stop()", self.naming_service_name)
if self.query_commandAlive() == True:
for sig, timeout in self.STOP_SIGNALS:
try:
os.kill(self._pid, sig)
except OSError:
self._pid = None
return
if timeout != None:
giveup_time = time.time() + timeout
while os.waitpid(self._pid, os.WNOHANG) == (0,0):
time.sleep(0.1)
if time.time() > giveup_time:
break
else:
# Wait until there is a response
os.waitpid(self._pid, 0)
self._pid = None
def stop(self):
self._log.debug("stop()")
if self.query_commandAlive() == True:
for sig, timeout in self.STOP_SIGNALS:
try:
os.kill(self._pid, sig)
except OSError:
self._pid = None
return
if timeout != None:
giveup_time = time.time() + timeout
while os.waitpid(self._pid, os.WNOHANG) == (0,0):
time.sleep(0.1)
if time.time() > giveup_time:
break
else:
# Wait until there is a response
os.waitpid(self._pid, 0)
self._pid = None
######################################
# Implement specific property setters/getters
def stop(self):
self._log.debug("stop()")
if self.query_commandAlive() == True:
for sig, timeout in self.STOP_SIGNALS:
try:
os.kill(self._pid, sig)
except OSError:
self._pid = None
return
if timeout != None:
giveup_time = time.time() + timeout
while os.waitpid(self._pid, os.WNOHANG) == (0,0):
time.sleep(0.1)
if time.time() > giveup_time:
break
else:
# Wait until there is a response
os.waitpid(self._pid, 0)
self._pid = None
######################################
# Implement specific property setters/getters
def stop(self):
self._log.debug("stop()")
try:
if self.get_commandAlive() == True:
for sig, timeout in self.STOP_SIGNALS:
try:
os.kill(self._pid, sig)
except OSError:
self._pid = None
return
if timeout != None:
giveup_time = time.time() + timeout
while os.waitpid(self._pid, os.WNOHANG) == (0,0):
time.sleep(0.1)
if time.time() > giveup_time:
break
else:
# Wait until there is a response
os.waitpid(self._pid, 0)
self._pid = None
finally:
Resource.stop(self)
# CF::LifeCycle
def stop(self):
self._log.debug("stop()")
try:
if self.get_commandAlive() == True:
for sig, timeout in self.STOP_SIGNALS:
try:
os.kill(self._pid, sig)
except OSError:
self._pid = None
return
if timeout != None:
giveup_time = time.time() + timeout
while os.waitpid(self._pid, os.WNOHANG) == (0,0):
time.sleep(0.1)
if time.time() > giveup_time:
break
else:
# Wait until there is a response
os.waitpid(self._pid, 0)
self._pid = None
finally:
Resource.stop(self)
# CF::LifeCycle
def stop(self):
self._log.debug("stop()")
if self.query_prop_commandAlive() == True:
for sig, timeout in self.STOP_SIGNALS:
try:
os.kill(self._pid, sig)
except OSError:
self._pid = None
return
if timeout != None:
giveup_time = time.time() + timeout
while os.waitpid(self._pid, os.WNOHANG) == (0,0):
time.sleep(0.1)
if time.time() > giveup_time:
break
else:
# Wait until there is a response
os.waitpid(self._pid, 0)
self._pid = None
######################################
# Implement specific property setters/getters
def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid,
_WNOHANG=os.WNOHANG, _os_error=os.error):
"""Check if child process has terminated. Returns returncode
attribute.
This method is called by __del__, so it cannot reference anything
outside of the local scope (nor can any methods it calls).
"""
if self.returncode is None:
try:
pid, sts = _waitpid(self.pid, _WNOHANG)
if pid == self.pid:
self._handle_exitstatus(sts)
except _os_error:
if _deadstate is not None:
self.returncode = _deadstate
return self.returncode
def kill(self):
if not self.qemu:
return
try:
self.qemu = None
os.kill(self.current_qemu_pid, signal.SIGKILL)
os.waitpid(self.current_qemu_pid, 0)
self.current_qemu_pid = -1
except OSError: # process may be finished by kill already
pass
LOG.debug('let gdb notice process was killed')
try:
execute_gdb_command('detach')
raise RuntimeError('gdb should have disconnected and raise gdb.error')
except gdb.error as e:
LOG.debug('catch expected exception: ' + str(e))
def kill_cmd(self):
if self.cmd_pid > 1:
try:
os.close(self.cmd_fd)
except OSError, e:
if e.errno == errno.EBADF:
pass # already closed
else:
raise e
try:
os.kill(self.cmd_pid, signal.SIGKILL)
os.waitpid(self.cmd_pid, 0)
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
self.cmd_pid = -1
def kill_cmd(self):
if self.cmd_pid > 1:
try:
os.close(self.cmd_fd)
except OSError, e:
if e.errno == errno.EBADF:
pass # already closed
else:
raise e
try:
os.kill(self.cmd_pid, signal.SIGKILL)
os.waitpid(self.cmd_pid, 0)
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
self.cmd_pid = -1
def _kill_ssh(self):
if self.ssh_pid > 1:
try:
os.kill(self.ssh_pid, signal.SIGTERM)
os.waitpid(self.ssh_pid, 0)
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
self.self_pid = -1
try:
os.close(self.ssh_fd)
except OSError, e:
if e.errno == errno.EBADF:
pass # already closed
else:
print 'WHAT?', e
raise e
def t4():
pretty = '%s t4' % __file__
print(pretty)
pid, fd = ave.cmd.run_bg('echo hello')
poller = select.poll()
poller.register(fd, select.POLLIN)
events = poller.poll(1000) # milliseconds
tmp = ''
for e in events:
if not (e[1] & select.POLLIN):
print('FAIL %s: unexpected poll event: %d' % (pretty, e[1]))
os.kill(pid, signal.SIGKILL)
tmp += os.read(fd, 1024)
if not tmp.startswith('hello'):
print('FAIL %s: wrong result: "%s"' % (pretty, tmp))
os.kill(pid, signal.SIGKILL)
os.waitpid(pid, 0)
return True
# check that return value from executed program is correct
def t4():
pretty = '%s t4' % __file__
print(pretty)
pid, fd = ave.cmd.run_bg('echo hello')
poller = select.poll()
poller.register(fd, select.POLLIN)
events = poller.poll(1000) # milliseconds
tmp = ''
for e in events:
if not (e[1] & select.POLLIN):
print('FAIL %s: unexpected poll event: %d' % (pretty, e[1]))
os.kill(pid, signal.SIGKILL)
tmp += os.read(fd, 1024)
if not tmp.startswith('hello'):
print('FAIL %s: wrong result: "%s"' % (pretty, tmp))
os.kill(pid, signal.SIGKILL)
os.waitpid(pid, 0)
return True
# check that return value from executed program is correct
def _waitpid(self, wanted_pid):
if wanted_pid:
if wanted_pid not in self.dict:
raise PtraceError("Unknown PID: %r" % wanted_pid, pid=wanted_pid)
debug("Wait process %s" % wanted_pid)
try:
pid, status = waitpid(wanted_pid, 0)
except OSError, err:
if err.errno == ECHILD:
process = self[wanted_pid]
raise process.processTerminated()
else:
raise err
else:
debug("Wait any process")
pid, status = waitpid(-1, 0)
if wanted_pid and pid != wanted_pid:
raise PtraceError("Unwanted PID: %r (instead of %s)"
% (pid, wanted_pid), pid=pid)
return pid, status
def reapProcess(self):
"""Try to reap a process (without blocking) via waitpid.
This is called when sigchild is caught or a Process object loses its
"connection" (stdout is closed) This ought to result in reaping all
zombie processes, since it will be called twice as often as it needs
to be.
(Unfortunately, this is a slightly experimental approach, since
UNIX has no way to be really sure that your process is going to
go away w/o blocking. I don't want to block.)
"""
try:
pid, status = os.waitpid(self.pid, os.WNOHANG)
except:
log.msg('Failed to reap %d:' % self.pid)
log.err()
pid = None
if pid:
self.processEnded(status)
unregisterReapProcessHandler(pid, self)
def wait(self):
"""Wait for child process to terminate. Returns returncode
attribute."""
while self.returncode is None:
try:
pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
except OSError as e:
if e.errno != errno.ECHILD:
raise
# This happens if SIGCLD is set to be ignored or waiting
# for child processes has otherwise been disabled for our
# process. This child is dead, we can't get the status.
pid = self.pid
sts = 0
# Check the pid and loop as waitpid has been known to return
# 0 even without WNOHANG in odd situations. issue14396.
if pid == self.pid:
self._handle_exitstatus(sts)
return self.returncode
def poll(self, flag=os.WNOHANG):
if self.returncode is None:
while True:
try:
pid, sts = os.waitpid(self.pid, flag)
except os.error as e:
if e.errno == errno.EINTR:
continue
# Child process not yet created. See #1731717
# e.errno == errno.ECHILD == 10
return None
else:
break
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 run(command):
# TODO: replace this with fork()
# (https://docs.python.org/2/library/os.html#os.fork)
pid = 0
if pid == 0:
# This is the child, we'll try to do some containment here
try:
contain(command)
except Exception:
traceback.print_exc()
os._exit(1) # something went wrong in contain()
# This is the parent, pid contains the PID of the forked process
# wait for the forked child and fetch the exit status
_, status = os.waitpid(pid, 0)
print('{} exited with status {}'.format(pid, status))
def run(image_name, image_dir, container_dir, command):
container_id = str(uuid.uuid4())
pid = os.fork()
if pid == 0:
# This is the child, we'll try to do some containment here
try:
contain(command, image_name, image_dir, container_id,
container_dir)
except Exception:
traceback.print_exc()
os._exit(1) # something went wrong in contain()
# This is the parent, pid contains the PID of the forked process
# wait for the forked child, fetch the exit status
_, status = os.waitpid(pid, 0)
print('{} exited with status {}'.format(pid, status))
def run(image_name, image_dir, container_dir, command):
container_id = str(uuid.uuid4())
pid = os.fork()
if pid == 0:
# This is the child, we'll try to do some containment here
try:
contain(command, image_name, image_dir, container_id,
container_dir)
except Exception:
traceback.print_exc()
os._exit(1) # something went wrong in contain()
# This is the parent, pid contains the PID of the forked process
# wait for the forked child, fetch the exit status
_, status = os.waitpid(pid, 0)
print('{} exited with status {}'.format(pid, status))
def run(image_name, image_dir, container_dir, command):
container_id = str(uuid.uuid4())
pid = os.fork()
if pid == 0:
# This is the child, we'll try to do some containment here
try:
contain(command, image_name, image_dir, container_id,
container_dir)
except Exception:
traceback.print_exc()
os._exit(1) # something went wrong in contain()
# This is the parent, pid contains the PID of the forked process
# wait for the forked child, fetch the exit status
_, status = os.waitpid(pid, 0)
print('{} exited with status {}'.format(pid, status))
def run(image_name, image_dir, container_dir, command):
container_id = str(uuid.uuid4())
pid = os.fork()
if pid == 0:
# This is the child, we'll try to do some containment here
try:
contain(command, image_name, image_dir, container_id, container_dir)
except Exception:
traceback.print_exc()
os._exit(1) # something went wrong in contain()
# This is the parent, pid contains the PID of the forked process
# wait for the forked child, fetch the exit status
_, status = os.waitpid(pid, 0)
print('{} exited with status {}'.format(pid, status))
def run(memory, memory_swap, cpu_shares, user, image_name, image_dir,
container_dir, command):
container_id = str(uuid.uuid4())
# linux.clone(callback, flags, callback_args) is modeled after the Glibc
# version. see: "man 2 clone"
flags = (linux.CLONE_NEWPID | linux.CLONE_NEWNS | linux.CLONE_NEWUTS |
linux.CLONE_NEWNET)
callback_args = (command, image_name, image_dir, container_id,
container_dir, cpu_shares, memory, memory_swap, user)
pid = linux.clone(contain, flags, callback_args)
# This is the parent, pid contains the PID of the forked process
# Wait for the forked child, fetch the exit status
_, status = os.waitpid(pid, 0)
print('{} exited with status {}'.format(pid, status))
def run(image_name, image_dir, container_dir, command):
container_id = str(uuid.uuid4())
pid = os.fork()
if pid == 0:
# This is the child, we'll try to do some containment here
try:
contain(command, image_name, image_dir, container_id, container_dir)
except Exception:
traceback.print_exc()
os._exit(1) # something went wrong in contain()
# This is the parent, pid contains the PID of the forked process
# wait for the forked child, fetch the exit status
_, status = os.waitpid(pid, 0)
print('{} exited with status {}'.format(pid, status))
def run(memory, memory_swap, cpu_shares, image_name, image_dir, container_dir,
command):
container_id = str(uuid.uuid4())
# linux.clone(callback, flags, callback_args) is modeled after the Glibc
# version. see: "man 2 clone"
flags = (linux.CLONE_NEWPID | linux.CLONE_NEWNS | linux.CLONE_NEWUTS |
linux.CLONE_NEWNET)
callback_args = (command, image_name, image_dir, container_id,
container_dir, cpu_shares, memory, memory_swap)
pid = linux.clone(contain, flags, callback_args)
# This is the parent, pid contains the PID of the forked process
# Wait for the forked child, fetch the exit status
_, status = os.waitpid(pid, 0)
print('{} exited with status {}'.format(pid, status))