Saltar al contenido

Lanzar un proceso completamente independiente

Esta reseña ha sido evaluado por expertos para asegurar la veracidad de esta noticia.

Solución:

Abres tu proceso de ejecución prolongada y mantener una pipa a ella. Así que esperas hablar con él. Cuando se cierra el script de inicio, ya no puede hablar con él. El proceso de larga duración recibe una SIGPIPE y salidas.

Lo siguiente me funcionó (Linux, Python 2.7).

Crea un ejecutable de larga duración:

$ echo "sleep 100" > ~/tmp/sleeper.sh

Ejecute Python REPL:

$ python
>>>

import subprocess
import os
p = subprocess.Popen(['/bin/sh', os.path.expanduser('~/tmp/sleeper.sh')])
# look ma, no pipes!
print p.pid
# prints 29893

Salga de REPL y vea que el proceso aún se está ejecutando:

>>> ^D
$ ps ax | grep sleeper
29893 pts/0    S      0:00 /bin/sh .../tmp/sleeper.sh
29917 pts/0    S+     0:00 grep --color=auto sleeper

Si desea comunicarse primero con el proceso iniciado y luego dejarlo solo para continuar, tiene algunas opciones:

  • Resolver SIGPIPE en su proceso de larga duración, no muera en él. En vivo sin stdin después de que finalice el proceso del iniciador.
  • Pase lo que quiera usando argumentos, entorno o un archivo temporal.
  • Si desea una comunicación bidireccional, considere usar una canalización con nombre (man mkfifo) o un socket, o escribir un servidor adecuado.
  • Haga que el proceso de ejecución prolongada se bifurque después de que se complete la fase de comunicación bidireccional inicial.

Puedes usar os.fork().

import os
pid=os.fork()
if pid==0: # new process
    os.system("nohup python ./myfile.py &")
    exit()
# parent process continues

No pude ver ningún proceso en ejecución.

No ve ningún proceso ejecutándose porque el niño python el proceso sale inmediatamente. los Popen los argumentos son incorrectos como dice el usuario 4815162342 en el comentario.

para lanzar un completamente independiente proceso, podrías usar python-daemon paquete o use systemd/supervisord/etc:

#!/usr/bin/python25
import daemon
from long_process import main

with daemon.DaemonContext():
    main()

Aunque podría ser suficiente en su caso, iniciar al niño con las Popen argumentos:

with open(os.devnull, 'r+b', 0) as DEVNULL:
    p = Popen(['/usr/bin/python25', '/path/to/long_process.py'],
              stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT, close_fds=True)
time.sleep(1) # give it a second to launch
if p.poll(): # the process already finished and it has nonzero exit code
    sys.exit(p.returncode)

Si el proceso hijo no requiere python2.5 entonces podrías usar sys.executable en su lugar (para usar la misma versión de Python que el padre).

Nota: el código se cierra DEVNULL en el padre sin esperar a que termine el proceso hijo (no tiene efecto en el hijo).

Aquí tienes las comentarios y valoraciones

Si te ha sido de provecho este post, sería de mucha ayuda si lo compartes con más seniors y nos ayudes a dar difusión a nuestro contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *