2009-09-18 21 views
16

Tôi có một chương trình viết để stdout và có thể stderr. Tôi muốn chạy nó từ python, bắt stdout và stderr. Mã của tôi trông giống như:Làm thế nào tôi có thể tìm hiểu lý do tại sao subprocess.Popen wait() chờ đợi mãi mãi nếu stdout = PIPE?

from subprocess import * 

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

Đối với một vài chương trình, điều này làm việc tốt, nhưng khi tôi thêm một chương trình mới, công cụ này sẽ hoạt động mãi mãi. Nếu tôi xóa stdout=PIPE, chương trình sẽ ghi kết quả đầu ra của nó vào bảng điều khiển và kết thúc và mọi thứ đều ổn. Làm cách nào tôi có thể xác định nguyên nhân gây ra sự cố?

Sử dụng python 2.5 trên Windows XP. Chương trình không đọc từ stdin cũng như không có bất kỳ loại đầu vào nào của người dùng (tức là "nhấn phím").

Trả lời

35

Khi đệm của một ống đầy lên (thường là 4KB hoặc lâu hơn), quá trình viết dừng lại cho đến khi một quá trình đọc đã đọc một số dữ liệu trong câu hỏi; nhưng ở đây bạn đang đọc không có gì cho đến khi tiến trình con được thực hiện, do đó bế tắc. The docs trên wait đặt nó rất rõ ràng thực sự:

Warning này sẽ bế tắc nếu quá trình con tạo ra đủ sản lượng đến một stdout hoặc stderr ống mà nó ngăn chặn chờ đợi cho các ống OS đệm để chấp nhận nhiều dữ liệu hơn. Sử dụng giao tiếp() để tránh điều đó.

Nếu bạn không thể sử dụng communicate đối với một số lý do, có ghi subprocess vào một tập tin tạm thời, và sau đó bạn có thể wait và đọc tập tin đó khi nó sẵn sàng - bằng văn bản cho một tập tin, thay vì để một ống , không có nguy cơ bế tắc.

+0

Bạn đã đánh bại tôi một chút. +1 – MitMaro

+0

Tệp trợ giúp được cài đặt với python 2.5 không có chút thông tin nhỏ. Cảm ơn –

+1

@Graeme, ah có, tài liệu của 2.6 được cải thiện đáng kể 2,5 wrt. –

1

Hãy xem qua số docs. Nó nói rằng bạn không nên sử dụng chờ đợi vì nó có thể gây ra một khóa chết. Hãy thử sử dụng communicate.

Các vấn đề liên quan