Python os 模块,killpg() 实例源码
我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用os.killpg()。
def terminate(self):
for child in self.__children:
child.terminate()
self.__children = []
for sig, timeout in self.STOP_SIGNALS:
try:
log.debug('Killing process group %s with signal %s', self.__process.pid, sig)
os.killpg(self.__process.pid, sig)
except OSError:
pass
giveup_time = time.time() + timeout
while self.__process.poll() is None:
if time.time() > giveup_time:
break
time.sleep(0.1)
if self.__process.poll() is not None:
break
self.__process.wait()
self.__process = None
def __terminate(self,pid):
sp = self._processes[pid]
for sig, timeout in self._STOP_SIGNALS:
try:
# the group id is used to handle child processes (if they
# exist) of the component being cleaned up
if _domainless._DEBUG == True:
print "_OutputBase: __terminate () making killpg call on pid " + str(pid) + " with signal " + str(sig)
_os.killpg(pid, sig)
except OSError:
log.error("_OutputBase: __terminate() OSERROR ===============")
pass
if timeout != None:
giveup_time = _time.time() + timeout
while sp.poll() == None:
if _time.time() > giveup_time: break
_time.sleep(0.1)
if sp.poll() != None: break
sp.wait()
def terminationHandler(cls, signal=None, frame=None, terminate=True):
"""Signal termination handler
signal - raised signal
frame - origin stack frame
terminate - whether to terminate the application
"""
#if signal == signal.SIGABRT:
# os.killpg(os.getpgrp(), signal)
# os.kill(os.getpid(), signal)
if cls._execpool:
del cls._execpool # Destructors are caled later
# Define _execpool to avoid unnessary trash in the error log, which might
# be caused by the attempt of subsequent deletion on destruction
cls._execpool = None # Note: otherwise _execpool becomes undefined
if terminate:
sys.exit() # exit(0), 0 is the default exit code.
def stop(self, signal=None):
"""Stop the heroku local subprocess and all of its children.
"""
signal = signal or self.int_signal
self.out.log("Cleaning up local Heroku process...")
if self._process is None:
self.out.log("No local Heroku process was running.")
return
try:
os.killpg(os.getpgid(self._process.pid), signal)
self.out.log("Local Heroku process terminated.")
except OSError:
self.out.log("Local Heroku was already terminated.")
self.out.log(traceback.format_exc())
finally:
self._process = None
def _kill_process(pid, sig):
"""
Sends the signal `sig` to the process identified by `pid`. If `pid` is a process group
leader, then signal is sent to the process group id.
"""
pgid = os.getpgid(pid)
try:
logvv('[{} sending {} to {}]'.format(os.getpid(), sig, pid))
if pgid == pid:
os.killpg(pgid, sig)
else:
os.kill(pid, sig)
return True
except:
log('Error killing subprocess ' + str(pid) + ': ' + str(sys.exc_info()[1]))
return False
def killProc(self):
global proc
try:
proc.terminate()
#os.killpg(proc.pid, signal.SIGKILL)
#print "after terminate: ", proc.pid
except:
pass
try:
proc.poll()
except:
pass
#os.killpg(proc.pid, signal.SIGTERM)
try:
del proc
except:
pass
if os.path.isfile('.target_fail'):
os.remove('.target_fail')
if os.path.isfile('.target_resp'):
os.remove('.target_resp')
def raise_sigint():
"""
Raising the SIGINT signal in the current process and all sub-processes.
os.kill() only issues a signal in the current process (without subprocesses).
CTRL+C on the console sends the signal to the process group (which we need).
"""
if hasattr(signal, 'CTRL_C_EVENT'):
# windows. Need CTRL_C_EVENT to raise the signal in the whole process group
os.kill(os.getpid(), signal.CTRL_C_EVENT)
else:
# unix.
pgid = os.getpgid(os.getpid())
if pgid == 1:
os.kill(os.getpid(), signal.SIGINT)
else:
os.killpg(os.getpgid(os.getpid()), signal.SIGINT)
def wait_on_children(self):
"""Wait on children exit."""
while self.running:
try:
pid, status = os.wait()
if os.WIFEXITED(status) or os.WIFSIGNALED(status):
self._remove_children(pid)
self._verify_and_respawn_children(pid, status)
except OSError as err:
if err.errno not in (errno.EINTR, errno.ECHILD):
raise
except KeyboardInterrupt:
LOG.info(_LI('Caught keyboard interrupt. Exiting.'))
os.killpg(0, signal.SIGTERM)
break
except exception.SIGHUPInterrupt:
self.reload()
continue
eventlet.greenio.shutdown_safe(self.sock)
self.sock.close()
LOG.debug('Exited')
def reload(self):
"""Reload and re-apply configuration settings.
Existing child processes are sent a SIGHUP signal and will exit after
completing existing requests. New child processes, which will have the
updated configuration, are spawned. This allows preventing
interruption to the service.
"""
def _has_changed(old, new, param):
old = old.get(param)
new = getattr(new, param)
return (new != old)
old_conf = self.stash_conf_values()
has_changed = functools.partial(_has_changed, old_conf, self.conf)
cfg.CONF.reload_config_files()
os.killpg(self.pgid, signal.SIGHUP)
self.stale_children = self.children
self.children = set()
# Ensure any logging config changes are picked up
logging.setup(cfg.CONF, self.name)
self.configure_socket(old_conf, has_changed)
self.start_wsgi()
def kill_last_pid():
"""Kill the last pid. See:
https://github.com/google/clusterfuzz-tools/issues/299"""
# We have found that, when invoking `sv stop python-daemon`, the process
# in call() isn't killed. Therefore, we need to explicitly kill it and
# all of its children.
#
# We hope that pid recycling is not that fast.
try:
with open(LAST_PID_FILE, 'r') as f:
pid = int(f.read().strip())
os.killpg(pid, signal.SIGKILL)
except: # pylint: disable=bare-except
pass
finally:
try:
os.remove(LAST_PID_FILE)
except: # pylint: disable=bare-except
pass
def kill(proc):
"""Kill a process multiple times.
See: https://github.com/google/clusterfuzz-tools/pull/301"""
try:
for sig in [signal.SIGTERM, signal.SIGTERM,
signal.SIGKILL, signal.SIGKILL]:
logger.debug('Killing pid=%s with %s', proc.pid, sig)
# Process leader id is the group id.
os.killpg(proc.pid, sig)
# Wait for any shutdown stacktrace to be dumped.
time.sleep(3)
raise error.KillProcessFailedError(proc.args, proc.pid)
except OSError as e:
if e.errno != NO_SUCH_PROCESS_ERRNO:
raise
def stop(self, wait=0.2):
if self.proc:
self.start_loading()
try:
logging.info("Stoping Engine " + self.name)
pid=self.proc.pid
#self.proc.stdout.close()
#self.proc.stdin.close()
#os.killpg(os.getpgid(pid), signal.SIGTERM)
self.proc.terminate()
if wait>0: sleep(wait)
try:
self.proc.kill()
os.killpg(pid, signal.SIGKILL)
except:
pass
except Exception as err:
logging.error("Can't stop engine %s => %s" % (self.name,err))
self.proc=None
self.stop_loading()
def run_and_timeout(self):
"""Run subprocess
Returns
-------
out : int
Exit code of subprocess
"""
self.start()
self.join(self.timeout)
if self.is_alive():
os.killpg(self.p.pid, signal.SIGTERM)
self.join()
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print(self.cmd)
print('Has run out of time')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
raise RuntimeError("3D-RISM calc didn't finish in time.")
def sigint_handler(sig, frame):
print("Killing sub-process...")
if process_handle is not None:
global kill_retry_count
while process_handle.returncode is None and kill_retry_count < kill_retry_max:
kill_retry_count += 1
print("Killing sub-process ({})...".format(kill_retry_count))
try:
os.killpg(os.getpgid(process_handle.pid), signal.SIGTERM)
os.waitpid(process_handle.pid, os.WNOHANG)
except ProcessLookupError:
break
try:
process_handle.wait(1)
except subprocess.TimeoutExpired:
pass
if working_dir is not None:
rmdir(working_dir)
sys.exit(0)
def stop(self):
"""Join the thread. Kill the running subprocess and interrupt the sleeping.
:return:
"""
self.is_running = False
if self.thread is not None:
# kill subprocess
if self.process is not None:
print("kill process")
try:
os.killpg(os.getpgid(self.process.pid), signal.SIGTERM)
except ProcessLookupError as e:
print(e)
# interrupt sleeping
self.stop_event.set()
self.stop_event = None
self.thread.join()
self.thread = None
def close(self):
''' Terminate the controller process and it's child processes.
Args:
- None
'''
if self.reuse :
logger.debug("Ipcontroller not shutting down: reuse enabled")
return
try:
pgid = os.getpgid(self.proc.pid)
status = os.killpg(pgid, signal.SIGTERM)
time.sleep(0.2)
os.killpg(pgid, signal.SIGKILL)
try:
self.proc.wait(timeout=1)
x = self.proc.returncode
logger.debug("Controller exited with {0}".format(x))
except subprocess.TimeoutExpired :
logger.warn("Ipcontroller process:{0} cleanup failed. May require manual cleanup".format(self.proc.pid))
except Exception as e:
logger.warn("Failed to kill the ipcontroller process[{0}]: {1}".format(self.proc.pid,
e))
def stop(self):
if self.process is None:
return
try:
os.killpg(os.getpgid(self.process.pid), self.stop_signal)
except OSError:
# Process is already gone
pass
else:
kill_time = time.time() + self.kill_after
while time.time() < kill_time:
if self.process.poll() is not None:
break
time.sleep(0.25)
else:
try:
os.killpg(os.getpgid(self.process.pid), 9)
except OSError:
# Process is already gone
pass
self.process = None
def econn():
global conn, address, ssh_server
ssh_server_check()
ssh_server = subprocess.Popen(['sudo', '/usr/sbin/sshd', '-p', '2222', '-f', '/etc/ssh/shareinator', '-D'],
preexec_fn=os.setsid)
socket_create()
socket_bind('', 9999)
# print('Waiting...')
try:
conn, address = s.accept()
return str(conn.recv(1024), encoding='utf-8')
except (KeyboardInterrupt, EOFError):
# print(' Keyboard Interrupt')
os.killpg(os.getpgid(ssh_server.pid), signal.SIGTERM)
return 0
# print(str(conn.recv(1024), encoding='utf-8'))
# confirmation = input("Do you want to accept the connection? ")
def stop(self):
"""Stop the emulator process.
Returns:
int: The process return code or None if the process isn't
currently running.
"""
if self._proc is not None:
if self._proc.poll() is None:
try:
os.killpg(self._proc.pid, signal.SIGTERM)
_, returncode = os.waitpid(self._proc.pid, 0)
self._logger.debug("Emulator process exited with code %d.", returncode)
return returncode
except ChildProcessError: # pragma: no cover
return self._proc.returncode
return self._proc.returncode # pragma: no cover
return None # pragma: no cover
def kill(self, group=True):
"""Kill the process. If group=True, all sub-processes will also be killed."""
self.kill_called = True
if mswindows:
if group and self._job:
winprocess.TerminateJobObject(self._job, 127)
else:
try:
winprocess.TerminateProcess(self._handle, 127)
except:
# TODO: better error handling here
pass
self.returncode = 127
else:
if group:
try:
os.killpg(self.pid, signal.SIGKILL)
except: pass
else:
os.kill(self.pid, signal.SIGKILL)
super(Popen, self).kill()
self.returncode = -9
def stop (self, wait_term=True, force=False):
if self.state != 'started':
return
self.dbg('Stopping')
try:
os.killpg(os.getpgid(self.proc.pid), signal.SIGTERM)
except OSError as e:
self.log('killpg() failed: already dead? (%s): ignoring' % str(e))
wait_term = False
if wait_term:
# Wait for termination
self.wait_stopped(timeout=10, force=force)
else:
self.state = 'stopped'
self.dbg('now %s, runtime %ds' % (self.state, self.runtime()))
self.stdout_fd.close()
self.stderr_fd.close()
self.proc = None
def startConsole(self, path, port=1):
"""
Import the php file/project AST from 'path' into the neo4j
database and start the neo4j console, using the 'SPAWN_SCRIPT' file.
"""
process = subprocess.call(
[
Configurator.getPath(Configurator.KEY_SPAWN_SCRIPT),
Configurator.getPath(Configurator.KEY_BASE_DIR) + "/config",
path, str(port),
"%d%s" % (Neo4jHelper.HEAP_SIZE[0],
Neo4jHelper.HEAP_SIZE[1])
],
preexec_fn=os.setsid
)
def signalHandler(signalnum, handler):
os.killpg(process.pid, signal.SIGINT)
signal.signal(signal.SIGINT, signalHandler)
signal.signal(signal.SIGTERM, signalHandler)
def execute(self,dt):
if self.finished: return "finished"
if not self.running:
self.process = Process(target = executeInProcessGroup, args = (self,))
self.process.start()
print "timeshare child PID:",self.process.pid
os.setpgid(self.process.pid,self.process.pid)
print "timeshare process group",os.getpgid(self.process.pid)
assert os.getpgid(self.process.pid) == self.process.pid
print "my process group",os.getpgrp(),"which should be",os.getpgid(0)
assert os.getpgid(self.process.pid) != os.getpgid(0)
self.running = True
else:
os.killpg(self.process.pid, signal.SIGCONT)
self.process.join(dt)
if self.process.is_alive():
os.killpg(self.process.pid, signal.SIGSTOP)
return "still running"
else:
self.finished = True
return self.q.get()
def exe(cmd, timeout=-1):
"""
Executes a command through the shell.
timeout in minutes! so 1440 mean is 24 hours.
-1 means never
"""
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, \
stderr=subprocess.STDOUT, close_fds=True,\
preexec_fn=os.setsid)
signal.signal(signal.SIGALRM, alarm_handler)
if timeout > 0:
signal.alarm(int(timeout*60))
try:
stdoutVal, stderrVal = proc.communicate()
signal.alarm(0) # reset the alarm
except Alarm:
logging.error(("Command was taking too long. "
"Automatic Timeout Initiated after %d" % (timeout)))
os.killpg(proc.pid, signal.SIGTERM)
proc.kill()
return 214,None,None
retCode = proc.returncode
return retCode,stdoutVal,stderrVal
def stop(self):
if self.process is None:
return
try:
os.killpg(os.getpgid(self.process.pid), self.stop_signal)
except OSError:
# Process is already gone
pass
else:
kill_time = time.time() + self.kill_after
while time.time() < kill_time:
if self.process.poll() is not None:
break
time.sleep(0.25)
else:
try:
os.killpg(os.getpgid(self.process.pid), 9)
except OSError:
# Process is already gone
pass
self.process = None
def _cleanup_http01_challenge(self, achall):
# pylint: disable=missing-docstring,unused-argument
if self.conf("test-mode"):
assert self._httpd is not None, (
"cleanup() must be called after perform()")
if self._httpd.poll() is None:
logger.debug("Terminating manual command process")
os.killpg(self._httpd.pid, signal.SIGTERM)
else:
logger.debug("Manual command process already terminated "
"with %s code", self._httpd.returncode)
shutil.rmtree(self._root)
#
# Installer section
#
def test__terminates_with_kill_and_killpg(self):
protocol = SignalPrinterProtocol()
process = yield self.startSignalPrinter(protocol, pgrp=True)
# Capture the pid now; it gets cleared when the process exits.
pid = process.pid
# Terminate and wait for it to exit.
self.terminateSignalPrinter(process, protocol)
yield protocol.done.addErrback(suppress, ProcessTerminated)
# os.kill was called once then os.killpg was called twice because the
# subprocess made itself a process group leader.
self.assertThat(
twisted_module._os_kill, MockCallsMatch(
mock.call(pid, signal.SIGTERM),
))
self.assertThat(
twisted_module._os_killpg, MockCallsMatch(
mock.call(pid, signal.SIGQUIT),
mock.call(pid, signal.SIGKILL),
))
def is_timeout(app, pr): # check if the process is active every 'factor' sec for timeout threshold
factor = 0.25
retcode = None
tt = cp.TIMEOUT_THRESHOLD * sp.apps[app][2] # sp.apps[app][2] = expected runtime
if tt < 10: tt = 10
to_th = tt / factor
while to_th > 0:
retcode = pr.poll()
if retcode is not None:
break
to_th -= 1
time.sleep(factor)
if to_th == 0:
os.killpg(pr.pid, signal.SIGKILL) # pr.kill()
print "timeout"
return [True, pr.poll()]
else:
return [False, retcode]
###############################################################################
# Run the actual injection run
###############################################################################
def run_server(self, language):
if language!=self.language and self.sentistrength:
logger.warning("wrong language running, trying to switch")
os.killpg(self.sentistrength.pid,15)
time.sleep(1)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect(('0.0.0.0',self.port))
except ConnectionRefusedError:
try:
logger.info("server not found, trying to launch server")
self.sentistrength = subprocess.Popen(["java -jar SentiStrengthCom.jar sentidata ./%s/ listen 8181 trinary" %language], shell=True, preexec_fn=os.setsid)
time.sleep(1)
sock.connect(('0.0.0.0',self.port))
self.language = language
except:
raise Exception("unable to start server, is there a process already running? ")
return sock
def stop_server(self, port=None,pid=None):
if port and pid:
logger.warn("this function requires EITHER a port OR a pid, ignores pid if both")
if port:
instance = [instance for instance in self.instances if instance['port']==port]
elif pid:
instance = [instance for instance in self.instances if instance['pid']==pid]
else:
instance = self.instances
if not instance:
logger.warn("Instance not found!")
return False
instance = instance[0]
os.killpg(instance['instance'].pid, 15)
time.sleep(1)
if not check_exists(instance['port']):
logger.info('Stopped {pid} instance at port {port}'.format(**instance))
self.instances.remove(instance)
return True
else:
logger.warn('Unable to stop {pid} instance running at {port}!!'.format(**instance))
return False
def send_signal(self, signum):
# if we have a local process, use its method, else determine if the ip is local or remote and issue
# the appropriate version to signal the process.
result = None
if self.local_proc:
if self.pgid > 0 and hasattr(os, "killpg"):
try:
os.killpg(self.pgid, signum)
return result
except OSError:
pass
result = self.local_proc.send_signal(signum)
else:
if self.ip and self.pid > 0:
if BaseProcessProxyABC.ip_is_local(self.ip):
result = self.local_signal(signum)
else:
result = self.remote_signal(signum)
return result
def test_log_follow():
wait_for_service('chronos')
proc = subprocess.Popen(['dcos', 'service', 'log', 'chronos', '--follow'],
preexec_fn=os.setsid,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
time.sleep(10)
proc.poll()
assert proc.returncode is None
os.killpg(os.getpgid(proc.pid), 15)
stdout = proc.stdout.read()
stderr = proc.stderr.read()
print('STDOUT: {}'.format(stdout))
print('STDERR: {}'.format(stderr))
assert len(stdout.decode('utf-8').split('\n')) > 3
def turn_off(self):
"""Turn the media player off."""
import pexpect
if self._pianobar is None:
_LOGGER.info('Pianobar subprocess already stopped')
return
self._pianobar.send('q')
try:
_LOGGER.info('Stopped Pianobar subprocess')
self._pianobar.terminate()
except pexpect.exceptions.TIMEOUT:
# kill the process group
os.killpg(os.getpgid(self._pianobar.pid), signal.SIGTERM)
_LOGGER.info('Killed Pianobar subprocess')
self._pianobar = None
self._player_state = STATE_OFF
self.schedule_update_ha_state()
def _checkpg(pid):
"""
Checks if any members of a process group are alive.
"""
try:
os.killpg(pid, 0)
return True
except OSError:
return False
def close(self):
"""Stops the process controller
Kill the process
"""
self.stop = True
try:
os.killpg(os.getpgid(self.process.pid), signal.SIGTERM)
except ProcessLookupError:
log_debug("Must already be dead")
else:
log_debug("Successfully killed")
ProcessController.instance = None
def keep_writing(self):
"""Input thread method for the process
Sends the user inputs (from InputTranscoder) to the process
"""
while True:
if self.stop:
break
ret = self.process.poll()
if ret is not None:
self.stop = True
readable, writable, executable = select.select([], [self.master], [], 5)
if writable:
try:
(input_type, content) = self.input_transcoder.pop_input(timeout=1)
except Empty:
pass
else:
if input_type == 0:
log_debug("Sending input\n<< {}".format(repr(content)))
data = content.encode('UTF-8')
# data = bytes(chaine, 'iso-8859-15')
while data:
chars_written = os.write(self.master, data)
data = data[chars_written:]
elif input_type == 1:
(signal_type, signal_content) = content
t = fcntl.ioctl(self.master, signal_type, signal_content)
log_debug(struct.unpack('HHHH', t))
elif input_type == 2:
os.killpg(os.getpgid(self.process.pid), content)
log_debug("SENDING SIGNAL TO PROCESS", content)
def tearDown(self):
#os.killpg(self.cloudverifier_process.pid, signal.SIGKILL)
pass
def sigterm_handler(self, signum, frame):
LOG.debug("Signal handler called with signal=%s" % signum)
global SIGTERM_SENT
if not SIGTERM_SENT:
LOG.info("Shutting down %s" % self.name)
SIGTERM_SENT = True
self.stop()
os.killpg(0, signal.SIGTERM)
sys.exit()
def kill(self):
pid = self.process.pid
if sublime.platform() == "windows":
kill_process = subprocess.Popen(['taskkill', '/F', '/T', '/PID', str(pid)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
kill_process.communicate()
else:
os.killpg(pid, signal.SIGTERM)
ProcessCache.remove(self)
def run(self, inp=None):
name = self.get_obj_file_name()
sandbox = Sandbox()
cmd = self.get_run_command(name, sandbox)
start = timer()
stdout = b''
stderr = b''
env = os.environ.copy()
r = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE, bufsize=4*1024,
cwd=MEDIA_ROOT, preexec_fn=os.setsid,env=env)
try:
if inp is not None:
stdout, stderr = r.communicate(timeout=timeout, input=inp.encode())
else:
stdout, stderr = r.communicate(timeout=timeout)
print('STDOUT : ' + str(stdout, "utf-8"))
print('STDERR : ' + str(stderr, "utf-8"))
except subprocess.TimeoutExpired as e:
print("Timeout expired")
os.killpg(r.pid, signal.SIGINT)
r.returncode = 124
print('Return Code : ' + str(r.returncode))
if self.lang != 'python':
os.remove(MEDIA_ROOT+'/'+name)
print('Elapsed seconds: {:.2f}'.format(timer() - start))
sandbox.delete_sandbox()
return Result(timer() - start, r.returncode, stdout)
def __exit__(self, type_, value, traceback):
print('cleanup: killing group for pid %d' % self.proc.pid)
os.killpg(os.getpgid(self.proc.pid), signal.SIGTERM)
def _reload_services(self, *args, **kwargs):
if self._shutdown.is_set():
# NOTE(sileht): We are in shutdown process no need
# to reload anything
return
# Reset forktimes to respawn services quickly
self._forktimes = []
signal.signal(signal.SIGHUP, signal.SIG_IGN)
os.killpg(0, signal.SIGHUP)
signal.signal(signal.SIGHUP, self._reload_services)
def _fast_exit(self, signo, frame,
reason='Caught SIGINT signal, instantaneous exiting'):
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGALRM, signal.SIG_IGN)
LOG.info(reason)
os.killpg(0, signal.SIGINT)
os._exit(1)
def kill_udocker_process(process):
logger.info("Stopping udocker container")
# Using SIGKILL instead of SIGTERM to ensure the process finalization
os.killpg(os.getpgid(process.pid), subprocess.signal.SIGKILL)
def make_terminate_handler(process, signal=signal.SIGTERM):
def inner(*args):
try:
os.killpg(os.getpgid(process.pid), signal)
except OSError:
pass
return inner
def shutdown():
if proc:
os.killpg(proc.pid, 2)
for d in [users, tmp, logs, topic]:
if os.path.isdir(d):
shutil.rmtree(d)
def terminate(end, proc, kill):
"""Terminate or kill the process after end."""
if not end or time.time() <= end:
return False
if kill: # Process will not die, kill everything
pgid = os.getpgid(proc.pid)
logging.info(
'Kill %d and process group %d', proc.pid, pgid)
os.killpg(pgid, signal.SIGKILL)
proc.kill()
return True
logging.info(
'Terminate %d on timeout', proc.pid)
proc.terminate()
return True
def _get_new_progress_group_args():
"""
Gets a tuple containing the `preexec_fn` and `creationflags` parameters to subprocess.Popen
required to create a subprocess that can be killed via os.killpg without killing the
process group of the parent process.
"""
preexec_fn = None
creationflags = 0
if not is_jython():
if get_os() == 'windows':
creationflags = subprocess.CREATE_NEW_PROCESS_GROUP
else:
preexec_fn = os.setsid
return preexec_fn, creationflags
def stop(self):
if self.process:
try:
os.killpg(os.getpgid(self.process.pid), signal.SIGTERM)
except OSError:
pass
def close(self):
if self.mpirun_proc is None:
return
if not self._tmpfile.closed:
self._tmpfile.close()
os.killpg(os.getpgid(self.mpirun_proc.pid), signal.SIGTERM)
os.killpg(os.getpgid(self.mpirun_proc.pid), signal.SIGKILL)
self.mpirun_proc.wait()
self.mpirun_proc = None