2010-03-11 29 views
7

Khi đọc về đường ống trong Lập trình nâng cao trong môi trường UNIX, tôi nhận thấy rằng sau ngã ba, cha mẹ có thể close() đầu đọc của ống và không đóng đầu đọc đứa trẻ. Khi một nhánh xử lý, các bộ mô tả tập tin của nó có được giữ lại không?Hành vi của một đường ống sau khi rẽ nhánh()

Ý tôi là trước khi ngã ba, bộ đọc mô tả tập tin có số lượng giữ lại là 1, và sau ngã ba 2. Khi cha mẹ đóng mặt đọc, fd chuyển thành 1 và được mở cho đứa trẻ. Đây có phải là những gì đang xảy ra không? Hành vi này cũng có xảy ra đối với các bộ mô tả tệp thông thường không?

Trả lời

5

Như người ta có thể đọc trên trang người đàn ông khoảng fork():

Quá trình trẻ em phải có bản sao riêng của tập tin của cha mẹ mô tả. Mỗi tệp trong số các tệp mô tả của trẻ em phải tham chiếu cùng một mô tả tệp mở với mô tả tệp tương ứng của phụ huynh .

Vì vậy, có, con có bản sao chính xác mô tả tệp của cha mẹ và đề cập đến tất cả chúng, bao gồm cả tệp đang mở.

+0

... trừ khi bạn thực hiện một số thủ thuật với http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html (mà bạn không nên, đó không phải là những gì nó có cho) – ephemient

+0

Chắc chắn, nhưng những gì bạn đã đăng không phải là 'fork()' mà là một biến thể của nó. – pajton

+0

Không, ý tôi là 'pthread_atfork' có thể thay đổi hành động của chương trình tại thời điểm' fork' thành (ví dụ) bao gồm các mô tả tệp đóng. Nhưng theo mặc định điều đó không xảy ra, và đó là một điều kỳ lạ để lạm dụng giao diện đó dù sao đi nữa. – ephemient

1

Có, một ngã ba trùng lặp tất cả các mô tả tệp đang mở.

Vì vậy, đối với một đường ống điển hình, một mảng 2 khe (int fd [2]), fd [0] giống nhau đối với cha mẹ và con, và do đó là fd [1].

Bạn có thể tạo một đường ống mà không cần nói gì cả, và đọc/ghi cho chính mình bằng cách sử dụng fd [0] và fd [1] trong một quá trình.

+1

Dẫn đến http://cr.yp.to/docs/selfpipe.html mẹo tuyệt vời! – ephemient

2

Câu trả lời là có, và có (điều tương tự áp dụng cho tất cả các bộ mô tả tệp, bao gồm những thứ như ổ cắm).

Trong cuộc gọi fork(), trẻ có bản sao riêng của từng bộ mô tả tệp, mỗi hành động giống như chúng đã được tạo bởi dup(). close() chỉ đóng bộ mô tả tệp cụ thể đã được chuyển - ví dụ: nếu bạn làm n2 = dup(n); close(n);, tệp (đường ống, ổ cắm, thiết bị ...) mà n đề cập đến vẫn mở - cũng áp dụng cho các mô tả tệp được sao chép bởi fork() .

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