español - Matando un subproceso incluyendo a sus hijos de python
subprocess python windows (2)
La solución obvia en este caso es no involucrar al shell :
import os
import subprocess
display = 0
log_file_path = "/tmp/selenium_log.txt"
selenium_port = 4455
selenium_folder_path = "/wherever/selenium/lies"
env = os.environ
env["DISPLAY"] = ":%d.0" % display
command = ["java",
"-server",
"-jar",
''selenium-server.jar'',
"-port",
str(selenium_port)]
log = open(log_file_path, ''a'')
selenium_server_process = subprocess.Popen(command,
cwd=selenium_folder_path,
stdout=log,
stderr=subprocess.STDOUT,
env=env)
Esto hará que el proceso sea el proceso de Java directamente. Tenga en cuenta que todavía puede generar procesos que no forman parte del grupo de procesos, por lo que os.killpg puede que aún no sepa cómo matarlos.
Si tiene una razón para invocar el shell (el código anterior no lo hace, y hay pocas cosas que no puede hacer sin el shell, pero suponga que sí), tendría que hacer que el shell le pase el pid del proceso que comenzó. de algun modo. Hacer esto no es sencillo, sino más bien situacional.
Esta pregunta ya tiene una respuesta aquí:
Estoy usando el módulo de subproceso en Python 2.5 para generar un programa java (el servidor de selenio, para ser precisos) de la siguiente manera:
import os
import subprocess
display = 0
log_file_path = "/tmp/selenium_log.txt"
selenium_port = 4455
selenium_folder_path = "/wherever/selenium/lies"
env = os.environ
env["DISPLAY"] = ":%d.0" % display
command = ["java",
"-server",
"-jar",
''selenium-server.jar'',
"-port %d" % selenium_port]
log = open(log_file_path, ''a'')
comm = '' ''.join(command)
selenium_server_process = subprocess.Popen(comm,
cwd=selenium_folder_path,
stdout=log,
stderr=log,
env=env,
shell=True)
Se supone que este proceso se mata una vez que se terminan las pruebas automatizadas. Estoy usando os.kill
para hacer esto:
os.killpg(selenium_server_process.pid, signal.SIGTERM)
selenium_server_process.wait()
Esto no funciona. La razón es que el subproceso de shell genera otro proceso para Java, y el código de Python desconoce el pid de ese proceso. He intentado matar el grupo de procesos con os.killpg
, pero eso mata también el proceso de python que ejecuta este código en primer lugar. Establecer shell en false, evitando así que Java se ejecute dentro de un entorno de shell, también está fuera de discusión, debido a otras razones.
¿Cómo puedo matar el shell y cualquier otro proceso generado por él?
Para manejar el problema general:
p=subprocess.Popen(your_command, preexec_fn=os.setsid)
os.killpg(os.getpgid(p.pid), signal.SIGTERM)
setsid
ejecutará el programa en una nueva sesión, asignándole así un nuevo grupo de proceso a él y sus hijos. llamar a os.killpg
en él, por lo tanto, no derribará tu propio proceso de Python también.