Saya punya dua program sederhana: A
dan B
. A
akan berjalan terlebih dahulu, kemudian B
mendapatkan "stdout" A
dan menggunakannya sebagai "stdin". Asumsikan saya menggunakan sistem operasi GNU / Linux dan cara paling sederhana untuk melakukan ini adalah:
./A | ./B
Jika saya harus menggambarkan perintah ini, saya akan mengatakan bahwa itu adalah perintah yang mengambil input (yaitu, dibaca) dari produsen ( A
) dan menulis ke konsumen ( B
). Apakah itu deskripsi yang benar? Apakah saya kehilangan sesuatu?
pipe
terminology
nihulus
sumber
sumber
Jawaban:
Satu-satunya hal tentang pertanyaan Anda yang salah adalah yang Anda katakan
Faktanya, kedua program akan dimulai pada waktu yang hampir bersamaan. Jika tidak ada input
B
ketika mencoba membaca, itu akan memblokir sampai ada input untuk dibaca. Demikian juga, jika tidak ada yang membaca output dariA
, maka penulisan akan memblokir sampai outputnya dibaca (beberapa akan buffered oleh pipa).Satu-satunya hal yang menyinkronkan proses yang mengambil bagian dalam pipa adalah I / O, yaitu membaca dan menulis melintasi pipa. Jika tidak ada penulisan atau pembacaan terjadi, maka kedua proses akan berjalan sepenuhnya independen satu sama lain. Jika salah satu mengabaikan pembacaan atau penulisan yang lain, proses yang diabaikan akan memblokir dan akhirnya dibunuh oleh
SIGPIPE
sinyal (jika menulis) atau mendapatkan kondisi file pada aliran input standar (jika membaca) ketika proses lain berakhir .Cara idiomatis untuk menggambarkan
A | B
adalah bahwa itu adalah pipa yang mengandung dua program. Output yang dihasilkan pada output standar dari program pertama tersedia untuk dibaca pada input standar oleh yang kedua ("[output]A
disalurkan ke [input]B
"). Shell melakukan plumbing yang diperlukan untuk memungkinkan hal ini terjadi.Jika Anda ingin menggunakan kata "konsumen" dan "produsen", saya rasa itu juga tidak masalah.
Fakta bahwa ini adalah program yang ditulis dalam C tidak relevan. Fakta bahwa ini adalah Linux, macOS, OpenBSD atau AIX tidak relevan.
sumber
mkfifo
untuk membuat pipa bernama, kemudian mulai B di latar belakang membaca dari pipa, dan kemudian menulis untuk itu. Ini adalah nit-picking, karena efeknya akan sama.yes | sed 10q
Istilah yang biasanya digunakan dalam dokumentasi adalah "pipeline", yang terdiri dari satu atau lebih perintah, lihat definisi POSIX. Jadi secara teknis, itu adalah dua perintah yang Anda miliki di sana, dua subproses untuk shell (baik
fork()+exec()
perintah eksternal atau subkulit).Sedangkan untuk bagian produsen-konsumen , pipa dapat dijelaskan dengan pola itu, karena:
/proc/<pid>/fd
direktori).stdout
dan konsumen membacastdin
seolah-olah mereka adalah perintah tunggal yang dieksekusi, alias mereka dapat hidup tanpa satu sama lain .Perbedaan yang saya lihat di sini adalah bahwa tidak seperti Produser-Konsumen di bahasa lain, perintah shell menggunakan buffering dan mereka menulis stdout setelah buffer diisi, tetapi tidak ada menyebutkan bahwa Konsumen-Konsumen harus mengikuti aturan itu - hanya menunggu ketika antrian diisi atau dibuang data (yang merupakan hal lain yang tidak dilakukan pipa).
sumber