Как запустить фоновый процесс в Python?
Я пытаюсь перенести сценарий оболочки в гораздо более читаемую версию python. Оригинальный скрипт запускает несколько процессов (утилиты, мониторы и т. д.) на заднем плане с"&". Как я могу достичь того же эффекта в Python? Я бы хотел, чтобы эти процессы не умирали, когда скрипты python завершатся. Я уверен, что это как-то связано с концепцией демона, но я не мог найти, как это сделать легко.
6 ответов
Примечание: этот ответ менее актуален, чем при публикации в 2009 году. С помощью subprocess
модуль, показанный в других ответах, теперь рекомендуется в документах
(обратите внимание, что модуль подпроцесса предоставляет более мощные средства для создания новых процессов и получения их результатов; использование этого модуля предпочтительнее использования этих функций.)
если вы хотите, чтобы ваш процесс начнется в фоновом режиме вы может либо использовать system()
и назовите его так же, как ваш сценарий оболочки, или вы можете spawn
это:
import os
os.spawnl(os.P_DETACH, 'some_long_running_command')
(или, альтернативно, вы можете попробовать менее портативный os.P_NOWAIT
флаг).
посмотреть документации.
пока jkpрешение работает, более новый способ делать вещи (и как рекомендует документация) - использовать subprocess
модуль. Для простых команд его аналог, но он предлагает больше возможностей, если вы хотите сделать что-то сложное.
пример для вашего случая:
import subprocess
subprocess.Popen(["rm","-r","some.file"])
Это должно работать rm -r somefile
на заднем плане. но будьте осторожны: subprocess.Popen()
запускает процесс только в фоновом режиме, если ничего в скрипте python не зависит от вывода выполняемой команды:
например, следующая команда не запустить в фоновом режиме:
import subprocess
ls_output=subprocess.Popen(["ls", "-a"], stdout=subprocess.PIPE)
см. документацию здесь.
кроме того, точка разъяснения: "фон" чисто концепция оболочки: то, что вы, вероятно, хотите, чтобы породить новый процесс. Я использовал " фон " здесь, чтобы ссылаться на shell-background-подобное поведение, но не путайте это с процессом, фактически находящимся в фон.
вы, вероятно, хотите ответ "как вызвать внешнюю команду в Python".
самый простой подход-использовать
Я нашел это здесь:
в windows (win xp) родительский процесс не завершится до longtask.py
завершила свою работу. Это не то, что вы хотите в CGI-скрипт. Проблема не специфична для Python, в сообществе PHP проблемы одинаковы.
решение-передать DETACHED_PROCESS
Флаг Создания Процесса в базовый CreateProcess
функция в win API. Если вы установили pywin32, вы можете импортировать флаг из модуль win32process, в противном случае вы должны определить его самостоятельно:
DETACHED_PROCESS = 0x00000008
pid = subprocess.Popen([sys.executable, "longtask.py"],
creationflags=DETACHED_PROCESS).pid
использовать subprocess.Popen()
С close_fds=True
параметр, который позволит порожденному подпроцессу быть отделенным от самого процесса Python и продолжать работать даже после выхода Python.
https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f
import os, time, sys, subprocess
if len(sys.argv) == 2:
time.sleep(5)
print 'track end'
if sys.platform == 'darwin':
subprocess.Popen(['say', 'hello'])
else:
print 'main begin'
subprocess.Popen(['python', os.path.realpath(__file__), '0'], close_fds=True)
print 'main end'
вы, вероятно, хотите начать исследовать модуль ОС для разветвления различных потоков (открыв интерактивный сеанс и выдав справку(os)). Соответствующими функциями являются fork и любой из exec. Чтобы дать вам представление о том, как начать, поместите что-то вроде этого в функцию, которая выполняет вилку (функция должна взять список или кортеж "args" в качестве аргумента, который содержит имя программы и ее параметры; вы также можете определить stdin, out и err для нового thread):
try:
pid = os.fork()
except OSError, e:
## some debug output
sys.exit(1)
if pid == 0:
## eventually use os.putenv(..) to set environment variables
## os.execv strips of args[0] for the arguments
os.execv(args[0], args)