Bagaimana memahami pipa

21

Ketika saya hanya menggunakan pipa di bash, saya tidak memikirkan hal ini. Tetapi ketika saya membaca beberapa contoh kode C menggunakan system call pipe () bersama dengan fork (), saya bertanya-tanya bagaimana memahami pipa, termasuk pipa anonim dan pipa bernama.

Sering terdengar bahwa "semua yang ada di Linux / Unix adalah file". Saya bertanya-tanya apakah pipa sebenarnya adalah file sehingga satu bagian yang terhubung menulis ke file pipa, dan bagian lainnya membaca dari file pipa? Jika ya, di mana file pipa untuk pipa anonim dibuat? Di / tmp, / dev, atau ...?

Namun, dari contoh pipa bernama, saya juga belajar bahwa menggunakan pipa memiliki keunggulan kinerja ruang dan waktu dibandingkan menggunakan file sementara secara eksplisit, mungkin karena tidak ada file yang terlibat dalam implementasi pipa. Juga tampaknya pipa tidak menyimpan data seperti file. Jadi saya ragu pipa sebenarnya adalah file.

Tim
sumber

Jawaban:

23

Tentang pertanyaan kinerja Anda, pipa lebih efisien daripada file karena tidak diperlukan IO disk. Jadi cmd1 | cmd2lebih efisien daripada cmd1 > tmpfile; cmd2 < tmpfile(ini mungkin tidak benar jika tmpfiledidukung pada disk RAM atau perangkat memori lain sebagai bernama pipa; tetapi jika itu adalah pipa bernama, cmd1harus dijalankan di latar belakang karena hasilnya dapat memblokir jika pipa menjadi penuh ). Jika Anda memerlukan hasil cmd1dan masih perlu mengirimkan outputnya cmd2, Anda harus cmd1 | tee tmpfile | cmd2yang akan mengizinkan cmd1dan cmd2menjalankan secara paralel menghindari operasi pembacaan disk cmd2.

Pipa Bernama berguna jika banyak proses membaca / menulis ke pipa yang sama. Mereka juga dapat berguna ketika suatu program tidak dirancang untuk menggunakan stdin / stdout karena IO-nya perlu menggunakan file . Saya meletakkan file dalam italic karena pipa bernama tidak persis file dalam sudut pandang penyimpanan karena mereka berada di memori dan memiliki ukuran buffer tetap, bahkan jika mereka memiliki entri sistem file (untuk tujuan referensi). Hal- hal lain dalam UNIX memiliki entri sistem file tanpa menjadi file: hanya memikirkan /dev/nullatau entri lain dalam /devatau /proc.

Karena pipa (dinamai dan tidak bernama) memiliki ukuran buffer tetap, operasi baca / tulis dapat diblokir, menyebabkan proses baca / tulis masuk dalam status IOWait. Juga, kapan Anda menerima EOF saat membaca dari buffer memori? Aturan tentang perilaku ini didefinisikan dengan baik dan dapat ditemukan pada pria.

Satu hal yang tidak dapat Anda lakukan dengan pipa (bernama dan tidak disebutkan namanya) adalah mencari kembali dalam data. Karena mereka diimplementasikan menggunakan buffer memori, ini bisa dimengerti.

Tentang "everything in Linux/Unix is a file", saya tidak setuju. Pipa bernama memiliki entri sistem file, tetapi tidak benar-benar file. Pipa yang tidak disebutkan namanya tidak memiliki entri sistem file (kecuali mungkin dalam /proc). Namun, sebagian besar operasi IO pada UNIX dilakukan dengan menggunakan fungsi baca / tulis yang memerlukan deskriptor file , termasuk pipa tanpa nama (dan soket). Saya tidak berpikir kita bisa mengatakan itu "everything in Linux/Unix is a file", tetapi kita pasti bisa mengatakan itu "most IO in Linux/Unix is done using a file descriptor".

jfg956
sumber
Terima kasih! Apakah dua perintah terhubung oleh pipa yang berjalan secara paralel, bukannya yang kedua mulai berjalan setelah yang pertama selesai?
Tim
Ya, 2 perintah dijalankan secara paralel. Jika tidak dan output pertama lebih dari buffer, itu akan diblokir. Anda dapat mencobanya dengan menjalankan cmd1 > fifodan cmd2 < fifodalam 2 shell yang berbeda, membuat pipa bernama dengan mkfifo fifo.
jfg956
Tes lain yang dapat Anda lakukan, adalah membunuh cmd2saat cmd1masih berjalan: cmd1mungkin akan berhenti melaporkan pesan pipa yang rusak.
jfg956
Terima kasih! apa maksudmu diblokir? Jika ini terjadi, apakah ini berarti tanggal dalam aliran setelah blok akan hilang?
Tim
2
Data tidak hilang. Jika penyangga pipa penuh, cmd1tulis ke pipa hanya akan kembali ketika cmd2akan membaca data dari pipa. Dengan cara yang sama, cmd2pembacaan dari pipa akan memblokir jika buffer kosong sampai cmd1menulis ke pipa.
jfg956
4

Dua dasar dasar filosofi UNIX adalah

  1. Untuk membuat program kecil yang melakukan satu hal dengan baik.
  2. dan mengharapkan output dari setiap program untuk menjadi input ke yang lain, seperti
    belum dikenal.

    Penggunaan pipa memungkinkan Anda memanfaatkan efek dari kedua desain ini
    dasar untuk membuat rantai perintah yang sangat kuat untuk mencapai hasil yang Anda inginkan.

    Sebagian besar program baris perintah yang beroperasi pada file juga dapat menerima input pada standar masuk (input melalui keyboard) dan output ke standar keluar (mencetak pada
    layar).

    Beberapa perintah dirancang untuk hanya beroperasi di dalam pipa yang tidak dapat beroperasi pada file secara langsung.

    misalnya trperintah

  ls -C | tr 'a-z' 'A-Z'
    cmd1 | cmd2
  • Mengirim STDOUT dari cmd1 ke STDIN dari cmd2 alih-alih layar.

  • STDERR tidak diteruskan melintasi pipa.

    Pendeknya Pipes is character (|) dapat menghubungkan perintah.

    Perintah apa pun yang menulis ke STDOUT dapat digunakan di sisi kiri pipa.

       ls - /etc | less 

    Perintah apa pun yang membaca dari STDIN dapat digunakan di sisi kanan pipa.

       echo "test print" | lpr 

    Pipa tradisional "tidak bernama" karena ada secara anonim dan tetap hanya selama proses itu berjalan. Pipa bernama adalah sistem-persisten dan ada di luar umur proses dan harus dihapus setelah tidak lagi digunakan. Proses umumnya melampirkan ke pipa bernama (biasanya muncul sebagai file) untuk melakukan komunikasi antar proses (IPC).

sumber: http://en.wikipedia.org/wiki/Named_pipe

mr_eclair
sumber
3

Untuk melengkapi jawaban lain ...

stdin dan stdout adalah deskriptor file dan dibaca serta ditulis seolah-olah mereka adalah file. karena itu Anda dapat melakukannya echo hi | grep hi, dan itu akan menggantikan stdout gema dengan pipa dan mengganti stdin grep ke ujung pipa ini.

pengguna606723
sumber
1

Semuanya adalah file.

Jika kita mengambil frasa terlalu harfiah, kita akan berakhir dengan makna "kita hanya punya file, dan tidak ada yang lain". Ini bukan interpretasi yang benar, jadi apa itu.

Ketika kita mengatakan "Semuanya adalah file", kita tidak mengatakan bahwa semuanya disimpan dalam disk. Kami mengatakan bahwa semuanya tampak seperti file, dapat dibaca, dapat ditulis.

Di Unix, sekali file, atau non-file terbuka, maka itu dapat diperlakukan seperti file. Namun tidak semua file mendukung semua operasi. Misalnya beberapa file (yang bukan file), tidak mendukung pencarian: mereka harus dibaca / ditulis secara berurutan (ini berlaku untuk pipa dan soket).

Semuanya memiliki nama file (pada beberapa sistem: misalnya Debian Gnu / Linux, dan banyak Gnu / Linux lainnya).

  • Semua file yang terbuka mendapatkan nama file. Lihat/proc/self/fd/…
  • Soket jaringan dapat dibuka dengan nama file lihat /dev/tcp
    misalnyacat </dev/tcp/towel.blinkenlights.nl/23
ctrl-alt-delor
sumber
Bagian terakhir itu hanya valid pada sistem dengan sistem /procfile, dan pada sistem (atau shell) yang menyediakan /dev/tcpstruktur file.
Kusalananda