2011-09-12 26 views
11

Đây là những gì tôi có thể đọc trong python module tài liệu trình con:stdout đóng cửa của đường ống python subprocess

Replacing shell pipeline 

    output=`dmesg | grep hda` 
    ==> 
    p1 = Popen(["dmesg"], stdout=PIPE) 
    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) 
    p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. 
    output = p2.communicate()[0] 

The p1.stdout.close() call after starting the p2 is important in order for p1 
to receive a SIGPIPE if p2 exits before p1. 

Tôi thực sự không hiểu tại sao chúng ta phải đóng p1.stdout sau khi đã tạo p2. Khi nào được thực thi chính xác p1.stdout.close()? Điều gì sẽ xảy ra khi p2 không bao giờ kết thúc? Điều gì sẽ xảy ra khi kết thúc hoặc p1 hoặc p2?

Trả lời

13

Từ Wikipedia, SIGPIPE là tín hiệu được gửi đến một quá trình khi cố ghi vào đường ống mà không có quá trình được kết nối với đầu kia.

Khi bạn tạo lần đầu tiên p1 sử dụng stdout=PIPE, có một quy trình được kết nối với đường ống, là quy trình Python của bạn và bạn có thể đọc kết quả bằng cách sử dụng p1.stdout.

Khi bạn tạo p2 sử dụng stdin=p1.stdout hiện có hai quy trình được kết nối với đường ống p1.stdout.

Nói chung khi bạn đang chạy quy trình trong một đường ống, bạn muốn tất cả các quy trình kết thúc khi bất kỳ quá trình nào kết thúc. Để điều này xảy ra tự động, bạn cần phải đóng p1.stdout vì vậy p2.stdin là quy trình duy nhất gắn liền với đường ống đó, theo cách này nếu kết quả là p2p1 ghi thêm dữ liệu vào stdout, nó sẽ nhận SIGPIPE vì không còn bất kỳ quy trình nào được đính kèm với đường ống đó nữa .

1

OK tôi hiểu. p1.stdout được đóng từ tập lệnh python của tôi nhưng vẫn mở ở p2, sau đó p1 và p2 liên lạc với nhau. Trừ khi p2 đã đóng, p1 sẽ nhận SIGPIPE. Tôi có đúng không?

+0

Điều đó là đúng, điều này quan trọng nếu quá trình đầu tiên có thể chạy lâu hơn quá trình thứ hai. –

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