2009-02-24 14 views
17

Nếu tôi có một chương trình tạo và cố gắng mở một đường ống có tên bằng mkfifo, làm thế nào tôi có thể mở một đường ống để đọc hoặc viết mà không bị chặn?Làm cách nào để thực hiện fopen không chặn trên ống có tên (mkfifo)?

Cụ thể, tôi đang viết chương trình C có thể chạy hoặc không có gui (viết bằng Java).

Trong chương trình C, tôi thành công tạo ra các đường ống đặt tên sử dụng mkfifo, tuy nhiên khi tôi làm

FILE* in = fopen(PIPE_IN, "r"); /* Where PIPE_IN is the filename*/ 

fopen không trả lại cho đến khi giao diện mở rằng ống cho văn bản. Những gì tôi muốn làm là có đường ống đã sẵn sàng để được đọc một lần (if) GUI quyết định ghi vào nó - tôi sẽ đặt bộ mô tả tập tin trong một cuộc gọi select(). Đó là hợp lý để mong đợi rằng GUI java có thể không bao giờ thực sự được bắt đầu, vì vậy tôi không thể dựa vào nó để mở đầu kia của đường ống tại bất kỳ điểm cụ thể hoặc thậm chí cả.

Tôi cũng sẽ có một ống thứ hai mở để viết, và tôi cho rằng tôi sẽ có cùng một vấn đề. Hơn nữa, tôi không thể đặt O_NONBLOCK trên một đường ống đầu ra không có đầu đọc.

Mọi đề xuất?

(Điều này được chạy trên một hệ thống Linux)

+0

Bạn có cần mở ống đầu ra trước khi chọn() kích hoạt trên ống đầu vào không? –

+0

@tinkertim - Tôi cho rằng về mặt kỹ thuật không - tôi đã thiết lập cả hai trong một chức năng thiết lập, nhưng tôi chỉ có thể thiết lập các đường ống đầu ra đầu tiên và sau đó gọi chọn, tại sao? – Zxaos

Trả lời

12

Bạn có thể open() ống của bạn O_RDONLY | O_NONBLOCK, và nếu bạn muốn dòng C, bạn có thể lấy nó với fdopen(). Tuy nhiên, có thể có vấn đề với select() - AFAIK, một đường ống mở để đọc mà không có nhà văn nào luôn được chuẩn bị để đọc và read() trả về 0, vì vậy, select() sẽ kích hoạt vô thời hạn.

Cách kludgy để khắc phục điều này sẽ là mở đường ống O_RDWR; có nghĩa là, có ít nhất một nhà văn (chương trình C++ của bạn). Mà sẽ giải quyết vấn đề của bạn anyway.

+1

Tôi sẽ cung cấp cho một shot cho người đọc - nhưng tôi không thể đặt O_NONBLOCK trên một đường ống đầu ra ... – Zxaos

+1

Tiêu chuẩn POSIX nói (của select()): "Bộ mô tả sẽ được xem là sẵn sàng để đọc khi có cuộc gọi với một chức năng đầu vào với O_NONBLOCK rõ ràng sẽ không chặn, có hay không chức năng sẽ chuyển dữ liệu thành công. " (POSIX.1: 2008). –

+1

Mở đường ống O_RDWR sẽ dẫn đến bế tắc khi chương trình đọc (hoặc ghi) - trừ khi có thực sự là một quá trình khác với đường ống mở. –