2009-04-03 21 views
8

Tôi có hai quy trình riêng biệt: một chương trình C xuất ra các giá trị được tách nhau bằng dấu phẩy, sau đó là dòng mới mỗi giây và chương trình Perl chấp nhận dữ liệu (cùng định dạng) và xử lý dữ liệu này.Làm cách nào để cho phép hai quy trình đồng thời giao tiếp?

Các đầu ra chương trình C (thông qua printf) đánh giá cao như vậy:

1, 2, 3, 4, 5, 6 
7, 8, 9, 10, 11, 12 
... 

Chương trình Perl ngồi trong một vòng lặp vô hạn chờ đợi theo phương pháp đường cho STDIN để xử lý dữ liệu này:

while ($line = <STDIN>) 
{ 
    chomp($line) # Line should now read "1,2,3,4,5,6" 
    # Process data 
} 

Tôi muốn hai quy trình này liên lạc trong thời gian thực. Ống bash tiêu chuẩn không hoạt động (ví dụ: process1 | process2) vì chương trình Perl chờ chương trình đầu tiên kết thúc trước khi xử lý đầu vào.

Có ai có bất kỳ ý tưởng, đề xuất hoặc thông tin chi tiết nào về giải pháp cho vấn đề này không? Cảm ơn bạn trước!

+0

nói đúng, điều này không liên quan gì đến "thời gian thực" – andersoj

+0

Bạn hoàn toàn đúng, tôi đã viết vội vàng và không thể nghĩ ra cách tốt hơn để giải thích cách tôi muốn các quy trình này hoạt động. Đồng thời có thể là một lựa chọn tốt hơn. –

+0

Đồng thời tốt hơn nhiều và có nút chỉnh sửa để bạn sửa lỗi. – derobert

Trả lời

16

Đường ống sẽ tốt cho việc này; bạn chỉ cần kiểm soát khi đầu ra của chương trình C của bạn được flushed để làm cho nó có sẵn cho các kịch bản perl gia tăng. Bạn có thể làm điều này trong chương trình C bằng cách sử dụng fflush(), sẽ buộc bộ đệm từ chương trình C của bạn được đẩy ra để chương trình perl có thể đọc nó.

Không có gì vốn có về các đường ống khiến chương trình perl đợi chương trình C kết thúc bằng văn bản trước khi xử lý đầu ra của nó. chương trình perl của bạn được viết sao cho nó xử lý STDIN một dòng tại một thời điểm:

while ($line = <STDIN>) { ... } 

<> trong bối cảnh này đọc một dòng từ STDIN, nhưng nếu không có một trong có sẵn nó sẽ chặn cho đến khi ai. Một cuộc gọi đến fflush() từ chương trình C sẽ làm cho điều này xảy ra.

Hãy xem Wikipedia article on Pipelines. Phần thực hiện cung cấp một mô tả ngắn gọn về cách các đường ống được đệm, điều này sẽ giúp bạn hiểu cách các quy trình của bạn giao tiếp. Ống làm cho phép tương tranh giữa các quy trình và quy trình đọc từ và ghi vào đường ống được quản lý bởi bộ lập lịch giống như các quy trình khác. Vấn đề của bạn ở đây là với bộ đệm.

+0

Tôi nghĩ rằng các chương trình C đã xóa sạch mọi đầu ra bất cứ khi nào chúng in một dòng mới. –

+0

Bạn đã đúng với câu trả lời này - tôi thậm chí đã khám phá fflush nhưng tôi không bao giờ nghĩ để sử dụng nó trên stdout.Và do tính chất của hành vi của chương trình perl, tôi đã nhầm nó vì 'chờ' trên chương trình c. Tôi đã thêm fflush (stdout) sau các câu lệnh printf của tôi và nó hoạt động hoàn hảo! Cảm ơn!! –

+0

@Chris Lutz, tự động tuôn ra chỉ xảy ra nếu luồng ở chế độ đệm theo dòng, thường chỉ đúng nếu luồng được mở trên một tty. Khi stdout là một đường ống, nó mặc định đệm đầy đủ cho hiệu suất tốt nhất. – RBerteig

5

Chương trình C sẽ fflush() các bộ đệm đầu ra của nó được giải thích, hoặc sử dụng một pty. Cái thứ hai khó xử hơn nhiều nhưng giữ mã C đơn giản hơn. Hãy thử "man 3 fflush" nếu điều này không quen thuộc với bạn.

+0

Sử dụng pty là quá mức cần thiết; đỏ bừng đầu ra là quan trọng nếu sử dụng stdio trong mã C (và không phải vật liệu nếu sử dụng write() trực tiếp). –

+0

Một pty chỉ cần thiết nếu hai tiến trình phải tương tác, và sau đó thực sự chỉ khi một hoặc cả hai phải không biết gì về việc có một con người không phải là bên tương tác. Ptys cũng không phải là rất di động bên ngoài của nền tảng unix giống như. – RBerteig

+0

Tôi đồng ý rằng pty là quá mức cần thiết, nhưng nó thủ thuật chương trình C để autoflush sau mỗi dòng mới. Trong ý nghĩa đó (và trong ý nghĩa đó thôi!) Nó làm cho chương trình C trở nên đơn giản hơn với chi phí của một môi trường phức tạp hơn. –

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