2009-09-11 39 views
10

Tôi đã hai chương trình Tôi đang sử dụng theo cách này:Bắt đầu ra của chương trình khác như là đầu vào một cách nhanh chóng

$ c_program | python_program.py 

c_program in cái gì đó sử dụng printf() và python_program.py nội dung đã sử dụng sys.stdin.readline()

tôi d muốn làm cho quá trình python_program.py xử lý đầu ra của c_program khi nó in, ngay lập tức, để nó có thể in đầu ra hiện tại của riêng nó. Thật không may python_program.py nhận được đầu vào của nó chỉ sau khi c_program kết thúc.

Tôi làm cách nào để giải quyết vấn đề này?

+0

Bạn đang nói đến bao nhiêu đầu ra? Có bộ đệm liên quan, vì vậy bất cứ điều gì dưới 4K sẽ luôn luôn là một điều duy nhất. –

+0

là không có cách nào để quyết định * khi * bộ đệm nên được đỏ mặt? –

Trả lời

17

Chỉ cần thiết lập stdout là dòng đệm ở đầu chương trình C của bạn (trước khi thực hiện bất kỳ đầu ra nào), như sau:

#include <stdio.h> 
setvbuf(stdout, NULL, _IOLBF, 0); 

hoặc

#include <stdio.h> 
setlinebuf(stdout); 

Hoặc ai sẽ làm việc trên Linux, nhưng setvbuf là một phần của tiêu chuẩn C vì vậy nó sẽ làm việc trên hệ thống hơn.

Theo mặc định, giá trị mặc định sẽ bị chặn theo bộ đệm cho đường ống hoặc tệp hoặc đường được lưu vào bộ đệm cho thiết bị đầu cuối. Kể từ khi stdout là một đường ống trong trường hợp này, mặc định sẽ được chặn đệm. Nếu nó là khối đệm sau đó bộ đệm sẽ được flushed khi nó là đầy đủ, hoặc khi bạn gọi fflush(stdout). Nếu nó là dòng đệm sau đó nó sẽ được tự động xả sau mỗi dòng.

+0

setvbuf hoạt động như một sự quyến rũ. Cảm ơn! –

+0

cảm ơn bạn rất nhiều. điều này đã giúp tôi trong srcds_linux để viết một thông minh hơn. tôi chỉ cần đặt nó như là plugin vào máy chủ trò chơi và voila .. stdout đi kèm trong dòng và không phải trong khối 4k. – GottZ

1

Tất cả các vỏ Unix (mà tôi biết) thực hiện đường ống vỏ thông qua một cái gì đó khác với một pty (thông thường, chúng sử dụng các đường ống Unix! -); do đó, thư viện thời gian chạy C/C++ trong cpp_program sẽ BIẾT đầu ra của nó KHÔNG phải là thiết bị đầu cuối, và do đó nó S buffer đệm đầu ra (theo khối của một vài KB tại một thời điểm). Trừ khi bạn viết shell của riêng bạn (hoặc semiquasimaybeshelloid) mà thực hiện đường ống thông qua pyt's, tôi tin rằng không có cách nào để làm những gì bạn yêu cầu bằng cách sử dụng ký hiệu đường ống.

Điều "shelloid" được đề cập có thể được viết bằng Python (hoặc trong C, hoặc Tcl, hoặc ...), sử dụng mô-đun pty của thư viện chuẩn hoặc mức trừu tượng cao hơn dựa trên nó như pexpect, và thực tế là hai chương trình được kết nối thông qua một "đường dẫn dựa trên pty" được viết bằng C++ và Python là khá không liên quan. Ý tưởng chính là để lừa chương trình bên trái của đường ống tin rằng stdout của nó là một thiết bị đầu cuối (đó là lý do tại sao một pty phải ở gốc của lừa) để đánh lừa thư viện thời gian chạy của nó vào NOT đệm đầu ra. Khi bạn đã viết một shelloid như vậy, bạn sẽ gọi nó bằng một số cú pháp như:

$ shelloid 'cpp_program | Tất nhiên nó sẽ dễ dàng hơn để cung cấp một "giải pháp điểm" bằng cách viết python_program trong kiến ​​thức rằng nó phải sinh ra cpp_program như là một tiến trình con và lừa nó tin rằng stdout của nó là một thiết bị đầu cuối (tức là, Ví dụ: python_program sau đó sẽ sử dụng trực tiếp pexpect). Nhưng nếu bạn có hàng triệu tình huống như vậy mà bạn muốn đánh bại bộ đệm bình thường được thực hiện bởi thư viện thời gian chạy C do hệ thống cung cấp, hoặc nhiều trường hợp bạn muốn sử dụng lại các bộ lọc hiện có, v.v, viết shelloid thực sự có thể thích hợp hơn.

1

Bạn có thể muốn thử flush nhập luồng stdout trong chương trình cpp.

8

Điều bạn cần là để chương trình C gọi fflush (stdout) sau mỗi dòng. Ví dụ, với công cụ grep GNU, bạn có thể gọi tùy chọn '--line-buffered', gây ra hành vi này. Xem fflush.

-1

ok này có lẽ âm thanh ngu ngốc nhưng nó có thể làm việc:

đầu ra PGM của bạn vào một tập tin

$ c_program >> ./out.log 

phát triển một chương trình python mà đọc từ lệnh đuôi

import os 

tailoutput = os.popen("tail -n 0 -f ./out.log") 

try: 
    while 1: 
     line = tailoutput.readline() 
     if len(line) == 0: 
      break 

     #do the rest of your things here 
     print line 

except KeyboardInterrupt: 
     print "Quitting \n" 
+1

Đáng buồn thay cho bạn, điều này sẽ không hoạt động. Vấn đề là chủ yếu là đầu ra của chương trình C được đệm, và không có gì bạn có thể làm trong chương trình Python để ảnh hưởng đến điều đó. Bạn phải sửa chương trình C sao cho đầu ra của nó không được đệm ngay cả khi đầu ra đi vào đường ống. –

6

Nếu bạn có thể sửa đổi chương trình C, bạn đã nhận được answer nhưng tôi nghĩ tôi sẽ đưa ra giải pháp cho những người không thể/sẽ không sửa đổi mã.

expect có một tập lệnh mẫu được gọi là unbuffer sẽ thực hiện thủ thuật.

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