2009-09-18 4 views
16

Mam program, który pisze do stdout i ewentualnie stderr. Chcę uruchomić go z Pythona, przechwytywanie stdout i stderr. Mój kod wygląda następująco:Jak mogę się dowiedzieć, dlaczego podproces.open wait() czeka na zawsze, jeśli stdout = PIPE?

from subprocess import * 

p = Popen(exe, shell=TRUE, stdout=PIPE, stderr=PIPE) 
rtrncode = p.wait() 

Przez kilka programów, to działa dobrze, ale gdy dodaje nowy, nowy wisi na zawsze. Jeśli usuniemy stdout=PIPE, program zapisze dane wyjściowe do konsoli i zakończy i wszystko będzie dobrze. Jak mogę ustalić, co powoduje zawieszenie?

Używanie Pythona 2.5 w Windows XP. Program nie czyta ze standardowego wejścia i nie ma żadnego rodzaju danych wejściowych od użytkownika (np. "Uderzenie w klawisz").

Odpowiedz

35

Gdy bufor rury napełnia się (zwykle około 4KB), proces pisania zostaje zatrzymany, dopóki proces czytania nie odczyta niektórych danych; ale tutaj nic nie czytasz, dopóki nie zostanie wykonany podproces, a więc i zakleszczenie. The docs na wait umieścić go bardzo wyraźnie rzeczywiście:

Warning W ten impas, jeśli proces dziecko generuje wystarczającą moc do stdout lub stderr rury tak, że blokuje czekają na rurze OS bufor przyjąć więcej danych. Użyj komendy(), aby tego uniknąć.

Jeśli nie można używać communicate z jakiegoś powodu mają zapis subprocess do tymczasowego pliku, a następnie można wait i odczytać ten plik, gdy będzie gotowa - zapis do pliku, zamiast do przewodu , nie ryzykuje impasu.

+0

Pobiłeś mnie trochę. +1 – MitMaro

+0

Plik pomocy zainstalowany w pythonie 2.5 nie ma zbyt małej ilości informacji. Dzięki –

+1

@Graeme, ah tak, dokumentacja 2.6 znacznie się poprawiła. –

1

Spójrz na docs. Stwierdza, że ​​nie powinieneś używać czekania, ponieważ może to spowodować martwą blokadę. Spróbuj użyć communicate.