Pipes pada POSIX

Pipes adalah perangkat komunikasi yang memungkinkan untuk melakuka komunikasi satu arah. Pipes diimplementasikan dalam file system. Pipes memiliki dua file offsets yaitu untuk membaca dan menulis. Pipes adalah pengankat serial, dimana data selalu dibaca urut sesuai dengan data yang pertama ditulis (FIFO) sehingga pipes sering dikatakan FIFO. Biasanya, pipe digunakan untuk berkomunikasi antara dua threads didalam single process atau diantara parent dan child process. Untuk efesiensi, pipes berada di core files, berada di memori bukan pada disk. Oleh karena itu  harus dibatasi ukurannya dengan membatasi jumlah blok pipe. (Dalam UNIX  pipes hanya menggunakan direct blocks).

Karena pipes memiliki ukuran yang terbatas dan akses FIFO yang ketat maka, proses baca dan tulis akan disinkronisasikan dengan cara yang sama dengan message buffers. Fungsi akses untuk pipes sama dengan files : WiteFile() dan ReadFile().

Dalam shell, symbol “|” digunakan untuk create pipe. Untuk contoh, shell ini  digunakan untuk membuat dua proses child, satu untuk “ls” dan satu untuk “less” :
        % ls | less

Shell ini juga menciptakan  sebuah pipe yang menghubungkan standar output dari “ls” subprocess dengan standar input dari “less” proses. Karena Kapasitas dari sebuah data pipe terbatas maka, ketika writer process membaca lebih cepat dari reader process mengkonsumsi data, dan jika pipe tidak dapat menyimpan lebih banyak data, writer process akan mem-block sampai tersedianya kasitas yang sesuai.  Jika reader mencoba untuk membaca tetapi data tidak tersedia, reader mem-block sampai data  kembali tersedia. Jadi, pipe secara otomatis mensinkronkan dua proses.

     Creating pipes

Untuk membuat  pipe, kita akan memanggil pipe command. Sediakan integer array dengan size 2.  Call pipe stores, pembacaan file descriptor dari array posisi 0 dan penulisan file descriptor dari posisi 1. Contohnya sebagai berikut :


int pipe_fds[2];
int read_fd;
int write_fd;

pipe (pipe_fds);
read_fd = pipe_fds[0];
write_fd = pipe_fds[1];

     Data ditulis kedalam file descriptor read_fd dan dapat dibaca kembali dari write_fd.

     Communication between Parent and child process

Sebuah pemanggilan pada pipe menciptakan file descriptors yang mana hanya valid pada proses tersebut dan child prosesnya. Sebuah proses file descriptors tidak dapat dikirim pada proses yang tidak berhubungan. Bagaimanapun ketika proses memanggil fork, file descriptors sedang dikopikan ke child proses yang baru. Pipes tersebut dapat dihubungkan hanya pada proses yang berelasi.

Pada contoh program sebuah fork menghasilkan child proses. Child proses tersebut mewarisi file descriptors pipe. Parentmenulis sebuah string ke pipe dan child membaca string tersebut. 

Diawal kita sudah mendeklarasi fds menjadi integer array dengan size 2. Pemanggilan pipe membuat sebuah pipe dan meletakan baca dan tulis file descriptor pada array. Program kemudian melakukan fork sebuah child proses. Setelah penutupan read diakhir pipe. Parent proses mulai menulis string pada pipe. setelah penutupan proses write pada akhir pipe, child proses membaca string dari pipe.

Sebagai catatan setelah melakukan fungsi penulisan. Parent melakukan flush pada pipe dengan menggunakan fflush. Sebaliknya string tidak akan dikirim secara cepat melalui pipe.

Ketika kita memanggil perintah ls|less dua fork terjadi: yang satu untuk ls child proses dan satu untuk less child proses. Kedua proses tersebut mewarisi pipe file descirptors untuk itu mereka berkomunikasi menggunakan pipe. untuk memiliki proses yang tidak saling berelasi digunakan FIFO.

      Redirecting the Standard Input, Output, and Error Streams

Jika ingin membuat proses child dan menset end of pipe sebagai standard input atau standar output. Menggunakan dup2 call, Kita bisa menyamakan satu file descriptor dengan yang lain. Misalnya, untuk mengarahkan proses input standar untuk file descriptor fd, dapat menggunakan baris ini:

            dup2 (fd, STDIN_FILENO);

symbol constant STDIN_FILENO  mewakili file description untuk standar input, yang memiliki nilai 0. Call close standar input dan reopens adalah duplikat dari fd sehingga keduanya dapat digunakan secara bergantian.  File descriptor menyetarakan berbagai posisi file yang sama dan set yang sama dari file status flags. Jadi, karakter read dari fd tidak dibaca kembali dari standar input.

      popen and pclose

penggunaan secara umum dari pipe adalah untuk mengirim data ke atau menerima dari program yang dijalankan dalam subproses.  Fungsi Popen dan pclose memudahkan paradigma yang ada dengan menghilangkan keperluan untuk memanggil pipe, fork, dup2, exec, dan fdopen. Berikut contoh penggunaanya:

#include <stdio.h>

#include <unistd.h>

int main ()

{

FILE* stream = popen (“sort”, “w”);

fprintf (stream, “This is a test.\n”);

fprintf (stream, “Hello, world.\n”);

fprintf (stream, “My dog has fleas.\n”);

fprintf (stream, “This program is great.\n”);

fprintf (stream, “One fish, two fish.\n”);

return pclose (stream);
}

      FIFOs
Firs-in first out (FIFO) file adalah sebuah pipe yang memiliki dalam filesistem. Setiap proses dapat membuka ataupun menutup FIFO. Proses pada setiap end pipe tidak perlu berhubungan satu sama lain. FIFOs juga disebut  named pipes. FIFO dapat dibuat dengan menggunakan perinta mkinfo. Tentukan path ke FIFO pada command line. Contohnya, create FIFO in/tmp/fifo  dengan menerapkan ini :

% mkfifo /tmp/fifo

% ls -l /tmp/fifo

prw-rw-rw- 1 euchant users 0 Jan 16 14:04 /tmp/fifo

Karakter pertama dari output dari ls adalah p, menunjukkan bahwa file ini sebenarnya adalah FIFO (named pipe). Dalam satu jendela, membaca dari FIFO dengan menerapkan ini:

% cat < /tmp/fifo

Pada jendela kedua, menulis ke FIFO dengan menerapkan ini:

% cat > /tmp/fifo

Lalu ketik di beberapa baris teks. Setiap kali Anda menekan Enter, baris teks yang dikirim melalui FIFO dan akan muncul di jendela pertama. Tutup FIFO dengan menekan Ctrl + D di jendela kedua. Hapus FIFO dengan baris ini:

% rm /tmp/fifo

Leave a Reply