Các ổ cắm tên miền FIFO, pipe & Unix có giống nhau trong nhân Linux không?


30

Tôi nghe nói rằng FIFO được đặt tên là ống. Và họ có chính xác cùng một ngữ nghĩa. Mặt khác, tôi nghĩ ổ cắm tên miền Unix khá giống với đường ống (mặc dù tôi chưa bao giờ sử dụng nó). Vì vậy, tôi tự hỏi nếu tất cả chúng đều đề cập đến cùng một triển khai trong nhân Linux. Bất kỳ ý tưởng?


Từ câu trả lời dưới đây, tôi nhận ra câu hỏi của mình khá mơ hồ và thật khó để trả lời. Có vẻ như không ai có thể biết nhiều chi tiết về công cụ triển khai trong kernel (ngay cả đối với các nhà phát triển kernel). Nếu ai đó có thể xác nhận rằng ổ cắm tên miền Unix, ống dẫn và FIFO thì tất cả đều đệm dữ liệu được gửi trong bộ nhớ dùng chung trong Linux, câu hỏi của tôi đã được giải quyết. Chà ... một phần đã được giải quyết.
Justin

FIFO = ống có tên! = Ống. Các bộ tứ có thể hai chiều giống như một cặp ổ cắm. Ống thường xuyên là đơn hướng. Tất cả đều có giao diện tập tin và ngữ nghĩa tập tin. Tại sao việc thực hiện lại quan trọng với bạn?
PSkocik

Tôi biết các đường ống là bộ đệm tròn và với hệ thống STREAM, chúng có thể được chia sẻ triển khai, tuy nhiên Linux không sử dụng STREAM theo mặc định. Tôi tin rằng Linux đã mã hóa các kênh IPC này. Tôi không cảm thấy muốn kiểm tra, mặc dù. : D Tại sao không phải là bạn? Mã này có sẵn công khai.
PSkocik

Nếu tất cả đều chia sẻ cùng một cách thực hiện, hiệu quả của chúng phải gần nhau. Và, với tôi, mã hạt nhân là quá khó hiểu.
Justin

Câu trả lời:


35

Các socket miền UNIX và FIFO có thể chia sẻ một phần triển khai của chúng nhưng về mặt khái niệm chúng rất khác nhau. Chức năng FIFO ở mức rất thấp. Một tiến trình ghi byte vào đường ống và một quá trình khác đọc từ nó. Ổ cắm tên miền UNIX có hành vi tương tự như ổ cắm TCP / IP.

Một ổ cắm là hai chiều và có thể được sử dụng bởi rất nhiều quá trình cùng một lúc. Một quy trình có thể chấp nhận nhiều kết nối trên cùng một ổ cắm và tham dự một số khách hàng cùng một lúc. Nhân cung cấp một bộ mô tả tệp mới mỗi lần connect(2)hoặc accept(2)được gọi trên ổ cắm. Các gói sẽ luôn đi đúng quy trình.
Trên một chiếc FIFO, điều này là không thể. Đối với sự kết hợp hai chiều, bạn cần hai FIFO và bạn cần một cặp FIFO cho mỗi khách hàng của mình. Không có cách viết hoặc đọc theo cách chọn lọc, bởi vì chúng là một cách nguyên thủy hơn nhiều để giao tiếp.

Ống vô danh và FIFO rất giống nhau. Sự khác biệt là các ống ẩn danh không tồn tại dưới dạng tệp trên hệ thống tệp nên không có quy trình nào có thể open(2). Chúng được sử dụng bởi các quy trình chia sẻ chúng bằng phương pháp khác. Nếu một quá trình mở một FIFO và sau đó thực hiện, ví dụ, a fork(2), con của nó sẽ kế thừa các mô tả tệp của nó và, trong số đó, đường ống.

Các ổ cắm tên miền UNIX, các đường ống ẩn danh và FIFO tương tự nhau trong thực tế chúng sử dụng các phân đoạn bộ nhớ dùng chung. Các chi tiết triển khai có thể thay đổi từ hệ thống này sang hệ thống khác nhưng ý tưởng luôn giống nhau: đính kèm cùng một phần bộ nhớ trong hai quá trình ánh xạ bộ nhớ riêng biệt để chúng chia sẻ dữ liệu
( chỉnh sửa: đó là một cách rõ ràng để thực hiện nó nhưng đó là không phải cách nó thực sự được thực hiện trong Linux, đơn giản chỉ sử dụng bộ nhớ kernel cho bộ đệm, xem câu trả lời của @ tjb63 bên dưới).
Nhân sau đó xử lý các cuộc gọi hệ thống và trừu tượng hóa cơ chế.


"Các ổ cắm tên miền UNIX và FIFO có thể chia sẻ một phần triển khai của chúng" ... vấn đề là "một phần của" ... Tôi mới nhận ra câu hỏi của mình là mơ hồ và thật khó để trả lời. Có vẻ như không ai có thể biết nhiều chi tiết về những phần họ chia sẻ trong kernel (ngay cả đối với các nhà phát triển kernel). Tuy nhiên ... bất cứ ai cũng có thể xác nhận rằng ổ cắm tên miền Unix, ống dẫn và FIFO tất cả đều đệm dữ liệu được gửi trong bộ nhớ dùng chung trong Linux? Nếu nó được xác nhận, câu hỏi của tôi đã được giải quyết. Chà ... một phần đã được giải quyết.
Justin

Vâng, vâng, có một bộ đệm được quản lý bởi kernel. Ví dụ, với FIFO, yoou có thể giết chết nhà văn và người đọc vẫn có thể gửi những gì đã được gửi vào đường ống trước cái chết của nhà văn. Với ổ cắm, nó phức tạp hơn một chút vì chúng hoạt động với giao thức được kết nối. Nhưng nếu bạn gửi, giả sử, một int đến socket, và sau đó thoát khỏi phạm vi để int bị xóa khỏi ngăn xếp của người gửi, người nhận vẫn có thể đọc nó. Vì vậy, rõ ràng có một bộ đệm ở đâu đó.
lgeorget

Đọc lại bình luận, không chắc là tôi rõ ràng ở đây ... Hãy cho tôi biết nếu vẫn còn điều gì đó không rõ ràng.
lgeorget

Nhận xét của bạn là rõ ràng với tôi.
Justin

7

Có một cuộc thảo luận khá tốt về vấn đề này ở đây: http://www.sl slideshoware.net/divyekapoor/linux-kernel-im THỰCation- of- pipes-and-fifos

Theo như tôi có thể thấy, cả từ các slide thuyết trình và nguồn @ http://lxr.free-electrons.com/source/fs/pipe.c - fifo được triển khai như một trình bao bọc xung quanh ống và chính chúng là thực hiện thông qua hệ thống tập tin ảo pipefs ..

@lgeorget - Các đường ống dường như sử dụng bộ nhớ kernel cho bộ đệm giữa người đọc và người viết - họ không sử dụng 'bộ nhớ chia sẻ' như vậy và sao chép bộ nhớ giữa không gian địa chỉ người dùng và hạt nhân (ví dụ: pipe_readcuộc gọi pipe_iov_copy_to_user, cuộc gọi __copy_to_user_inatomic(hoặc copy_to_user) . __copy_to_user_inatomiccuộc gọi copy_user_generic, mà là trên một số triển khai ASM.


4

Một "FIFO" và " ống có tên " là như nhau - mặc dù nó khác hoàn toàn với cách một shell xử lý một "ống" (|) giữa hai lệnh trên dòng lệnh.

Một ống có tên (FIFO) là một "tệp" được chia sẻ bởi hai chương trình, trong đó một chương trình ghi vào đó và một kênh khác đọc từ đó ... Mặt khác, một ổ cắm là "kết nối" giữa hai "tệp" - có thể sử dụng một mạng và ở trên các máy tính riêng biệt - trong đó một chương trình đọc / ghi vào một "tệp" và một chương trình khác đọc / ghi vào chương trình kia ... Tôi không nghĩ chúng giống nhau ... Mặt khác cả hai ổ cắm và đường ống có tên - cũng như các tệp, thiết bị, liên kết tượng trưng - tất cả đều sử dụng inodes và tất cả chúng đều thực hiện một số tính năng phổ biến (như đọc và ghi).


1
Đúng, ổ cắm tên miền Unix là loại ổ cắm, do đó, API của nó tương tự như các API ổ cắm khác như TCP hoặc UDP, v.v. Tuy nhiên, ổ cắm tên miền Unix chỉ có thể được sử dụng làm IPC "cục bộ". Và cách nó truyền dữ liệu theo cách đầu tiên, gần giống như FIFO & pipe. Vì vậy, tôi nghĩ rằng API của ổ cắm tên miền Unix có thể chỉ là một đóng gói khác của việc triển khai giống hệt nhau nên chúng tôi sử dụng nó như thể nó là một ổ cắm. Tôi nghĩ có thể tất cả họ đều chia sẻ cùng một nội bộ trong kernel ... Tôi muốn xác nhận xem điều đó có đúng hay không.
Justin

1

Tôi không nghĩ vậy Justin. Nếu tôi không nhầm, và tôi hoàn toàn có thể là tôi, tôi nghĩ rằng các FIFO sử dụng một tệp trên đĩa và các ổ cắm tên miền Unix sử dụng bộ nhớ kernel.

Ngoài ra, như một phần bổ sung cho người đăng ở trên, người đã đề cập rằng các ổ cắm tên miền Unix là hai chiều, đó chỉ là trường hợp khi sử dụng ổ cắm SOCK_STREAM. Trên thực tế, các ổ cắm tên miền SOCK_DGRAM Unix là đơn hướng và chỉ có thể gửi () từ mã được gọi là connect (), đến mã được gọi là bind ().

Tất nhiên, mã được gọi là connect () cũng phải gọi bind () để tạo điểm cuối riêng của nó, nhưng điều đó không liên quan gì đến câu hỏi của bạn.


3
Chào mừng bạn đến với StackExchange và cảm ơn bạn đã đăng bài. Một vài lưu ý ... 1) Nếu bạn "hoàn toàn có thể" nhầm, bạn nên kiểm tra kỹ trước khi trả lời; Trang web này không phải là một diễn đàn cũng không phải là một cuộc trò chuyện. 2) Cảm ơn sự chính xác của bạn trên các socket định hướng datagram 3) Không cần phải đăng một cái gì đó "không có gì để làm" với câu hỏi. :)
lgeorget

1

2 xu của tôi ... Ổ cắm FIFO và UNIX đều là hai hướng (tương tự) nhưng ổ cắm có cấu trúc liên kết sao trong khi FIFO chỉ là một hàng đợi (và do đó không thể thay thế nhau), có, việc triển khai của chúng có thể chia sẻ mã bên trong.

**

char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDWR);   //so that you can read/write to it
 ...
write(fd, buff1, sizeof(buff1));  
getchar();//wait till some one reds this and writes something else
int sz=read(fd, buff1, sizeof(buff1));  //read that something**

FIFO là hai chiều?
jhfrontz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.