Saya telah membaca tentang bagaimana pipa diimplementasikan di kernel Linux dan ingin memvalidasi pemahaman saya. Jika saya salah, jawaban dengan penjelasan yang benar akan dipilih.
- Linux memiliki VFS yang disebut pipef yang dipasang di kernel (bukan di ruang pengguna)
- pipefs memiliki super blok tunggal dan dipasang di root sendiri (
pipe:
), di samping/
- pipef tidak dapat dilihat secara langsung tidak seperti kebanyakan sistem file
- Entri ke pipef adalah melalui
pipe(2)
syscall - The
pipe(2)
syscall digunakan oleh kerang untuk pipa dengan|
operator (atau manual dari proses lainnya) membuat file baru di pipefs yang berperilaku cukup banyak seperti file normal - File di sisi kiri operator pipa
stdout
dialihkan ke file sementara yang dibuat di pipefs - File di sisi kanan operator pipa memiliki
stdin
set ke file di pipefs - pipef disimpan dalam memori dan melalui beberapa kernel sulap, tidak boleh halaman
Apakah penjelasan tentang cara kerja pipa (mis. ls -la | less
) Ini benar?
Satu hal yang saya tidak mengerti adalah bagaimana sesuatu seperti bash akan mengatur proses ' stdin
atau stdout
ke file descriptor yang dikembalikan oleh pipe(2)
. Saya belum dapat menemukan apa pun tentang itu.
pipe()
panggilan kernel bersama dengan mesin yang mendukung itu (pipefs
, dll) adalah tingkat yang lebih rendah dari|
operator yang ditawarkan dalam shell Anda. Yang terakhir biasanya diimplementasikan menggunakan yang pertama, tetapi tidak harus.|
operator hanya memanggilpipe(2)
sebagai proses seperti halnya bash.Jawaban:
Analisis Anda sejauh ini umumnya benar. Cara sebuah shell dapat mengatur stdin dari suatu proses menjadi deskriptor pipa bisa menjadi (pseudocode):
sumber
dup2
panggilan itu diperlukan, dan Anda tidak bisa langsung menetapkan deskriptor pipa ke stdin?pipe()
. Thedup2()
panggilan memungkinkan penelpon untuk menyalin file descriptor untuk nilai numerik tertentu (diperlukan karena 0, 1, 2 yang stdin, stdout, stderr). Itu setara dengan kernel dari "menetapkan langsung ke stdin". Perhatikan bahwa variabel global C runtime librarystdin
adalah aFILE *
, yang tidak terkait dengan kernel (meskipun diinisialisasi untuk dihubungkan ke deskriptor 0).dup2
Panggilan tidak berubahp[1]
. Sebagai gantinya, ia membuat kedua peganganp[1]
dan0
menunjuk ke objek kernel yang sama (pipa). Karena proses anak tidak memerlukan dua pegangan stdin (dan tidak akan tahu apa pegangan nomor itup[1]
,)p[1]
ditutup sebelumnyaexec
.