Saya mendengar bahwa FIFO dinamai pipa. Dan mereka memiliki semantik yang persis sama. Di sisi lain, saya pikir soket domain Unix sangat mirip dengan pipa (walaupun saya tidak pernah memanfaatkannya). Jadi saya bertanya-tanya apakah mereka semua merujuk pada implementasi yang sama di kernel Linux. Ada ide?
30
Jawaban:
Soket domain UNIX dan FIFO dapat berbagi sebagian dari implementasinya tetapi secara konsep mereka sangat berbeda. FIFO berfungsi pada level yang sangat rendah. Satu proses menulis byte ke dalam pipa dan yang lain membaca dari itu. Soket domain UNIX memiliki perilaku yang sama dengan soket TCP / IP.
Soket adalah dua arah dan dapat digunakan oleh banyak proses secara bersamaan. Suatu proses dapat menerima banyak koneksi pada soket yang sama dan menghadiri beberapa klien secara bersamaan. Kernel mengirimkan deskriptor file baru setiap kali
connect(2)
atauaccept(2)
dipanggil pada socket. Paket akan selalu menuju ke proses yang benar.Pada FIFO, ini tidak mungkin. Untuk komunikasi dua arah, Anda memerlukan dua FIFO, dan Anda membutuhkan sepasang FIFO untuk masing-masing klien Anda. Tidak ada cara menulis atau membaca secara selektif, karena mereka jauh lebih primitif untuk berkomunikasi.
Pipa anonim dan FIFO sangat mirip. Perbedaannya adalah bahwa pipa anonim tidak ada sebagai file pada sistem file sehingga tidak ada proses yang bisa
open(2)
. Mereka digunakan oleh proses yang membagikannya dengan metode lain. Jika suatu proses membuka FIFO dan kemudian melakukan, misalnya, afork(2)
, anaknya akan mewarisi deskriptor file dan, di antaranya, pipa.Soket domain UNIX, pipa anonim dan FIFO serupa dalam kenyataan mereka menggunakan segmen memori bersama. Detail implementasi dapat bervariasi dari satu sistem ke sistem lain tetapi idenya selalu sama:
lampirkan bagian memori yang sama dalam dua proses pemetaan memori yang berbeda untuk meminta mereka berbagi data( edit: itu akan menjadi satu cara yang jelas untuk mengimplementasikannya tetapi itu adalah bukan bagaimana ini sebenarnya dilakukan di Linux, yang hanya menggunakan memori kernel untuk buffer, lihat jawabannya oleh @ tjb63 di bawah).
Kernel kemudian menangani pemanggilan sistem dan mengabstraksi mekanisme tersebut.
sumber
Ada diskusi yang cukup baik tentang ini di sini: http://www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos
Sejauh yang saya bisa lihat, baik dari slide presentasi, dan sumber @ http://lxr.free-electrons.com/source/fs/pipe.c - fifo diimplementasikan sebagai pembungkus di sekitar pipa, dan pipa itu sendiri adalah diimplementasikan melalui sistem file virtual pipefs ..
@ lgeorget - Pipa tampaknya menggunakan memori kernel untuk buffer antara pembaca dan penulis - mereka tidak menggunakan 'memori bersama' seperti itu, dan menyalin memori antara ruang alamat pengguna dan kernel (misalnya,
pipe_read
panggilanpipe_iov_copy_to_user
, yang memanggil__copy_to_user_inatomic
(ataucopy_to_user
) .__copy_to_user_inatomic
panggilancopy_user_generic
, yang pada beberapa implementasi ASM.sumber
"FIFO" dan " pipa bernama " adalah hal yang sama - meskipun sangat berbeda dari bagaimana shell menangani "pipa" (|) antara dua perintah pada baris perintah.
Pipa bernama (FIFO) adalah "file" tunggal yang dibagikan oleh dua program, di mana satu menulis ke sana dan yang lain membaca darinya ... Soket di sisi lain adalah "koneksi" antara dua "file" - yang mungkin menggunakan jaringan dan berada di komputer yang terpisah - di mana satu program membaca / menulis ke satu "file" dan program lain membaca / menulis ke yang lain ... Saya tidak berpikir mereka sama ... Di sisi lain keduanya soket dan pipa bernama - serta file, perangkat, tautan simbolik - semua menggunakan inode, dan mereka semua mengimplementasikan beberapa fitur umum (seperti membaca dan menulis).
sumber
Kurasa tidak, Justin. Jika saya tidak salah, dan saya sangat mungkin, saya pikir FIFO menggunakan file pada disk, dan soket Unix Domain menggunakan memori kernel.
Juga, sebagai tambahan pada poster di atas yang menyebutkan bahwa soket domain Unix adalah dua arah, itu hanya merupakan kasus ketika menggunakan soket SOCK_STREAM. SOCK_DGRAM Soket domain unix sebenarnya adalah uni-directional, dan hanya dapat mengirim () dari kode yang disebut connect (), ke kode yang disebut bind ().
Tentu saja, kode yang disebut connect () juga harus memanggil bind () untuk membuat titik akhir sendiri, tetapi itu tidak ada hubungannya dengan pertanyaan Anda.
sumber
2 sen saya ... FIFO dan UNIX socket keduanya bi-directional (mirip) tetapi socket memiliki topologi bintang sedangkan FIFO hanya antrian (dan karenanya tidak dapat saling menggantikan), ya implementasinya dapat berbagi kode secara internal.
**
sumber