2010-12-07 3 views
1

Я пробовал как pexpect, так и subprocess.Popen из python для вызова внешнего долгосрочного фонового процесса (этот процесс использует сокет для связи с внешними приложениями) со следующими подробностями.вопрос о pexpect в python

  1. subprocess.Popen (launchcmd, STDIN = subprocess.PIPE, стандартный вывод = subprocess.PIPE, STDERR = subprocess.PIPE) Это прекрасно работает. Мне не нужно ничего делать. Однако, поскольку я должен немедленно получить результат, я выбираю pexpect, чтобы избежать проблемы с буферным файлом.

  2. OBJ = pexpect.spawn (launchcmd, тайм-аут = None) после запуска внешнего процесса, я использую отдельный поток, чтобы сделать «Readline» читать вывод запущенного процесса «OBJ», и все в порядке.

  3. obj = pexpect.spawn (launchcmd, timeout = None) После запуска внешнего процесса я больше ничего не делал, т. Е. Просто оставил его там. Хотя, используя команду «ps -e», я могу найти запущенный процесс, но запущенный процесс кажется заблокированным и не может связываться в сокетах с другими приложениями.

OK. Чтобы быть более конкретным, я поставил несколько примеров кода, чтобы сформулировать мой вопрос.

import subprocess 
import pexpect 
import os 

t=1 
while(True): 
    if(t==1): 
     background_process="./XXX.out" 
     launchcmd = [background_process] 
     #---option 3-------- 
     p=pexpect.spawn(launchcmd, timeout=None) # process launced, problem with socket. 
     #---option 1-------- 
     p=subprocess.Popen(launchcmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # process launced, everything fine 
     t=0 

Может ли кто-нибудь сказать мне, что случилось с третьим вариантом? И если это связано с тем, что я не использовал отдельный поток для управления выходом, почему 1-й вариант работает с subprocess.popen? Я подозреваю, что что-то не так с pexpect для запуска процесса с использованием сокета, но я не уверен, особенно учитывая, что вариант 2 работает хорошо.

+0

Я думаю, что вы можете ошибаться в различии между трубопроводами и буферами - труба - это просто канал, если он буферизирован или не зависит от приложения, которое (прежде чем читать). Readline - буферизация - пока вы не получите новую строку. read() буферизуется, потому что читает, пока не получит EOF. Первый пример, который вы предоставляете, должен быть хорошим, если есть данные для чтения, вы его получите, но если ваш запускcmd буферизуется, он не будет мгновенным. – synthesizerpatel 2010-12-07 12:41:17

ответ

1

Я думаю, что вы делаете это слишком сложным.

Да, это хорошая идея, чтобы использовать pty вместо pipe взаимодействовать с фоновым процессом, так как большинство приложений распознают TTY устройство/PTy и переключиться на использование небуферизованного выхода, (или, по крайней мере линейный буфер).

Но почему pexpect? Просто используйте pty-модуль Python. Сначала вызовите openpty, чтобы получить некоторые дескрипторы файлов, а затем используйте Popen, чтобы запустить процесс. Пример кода можно найти в следующем вопросе (ответ с зеленой галочкой) Python Run a daemon sub-process & read stdout