Apa jaminan untuk menulis bersamaan ke pipa bernama?

32

Misalnya, saya membuat pipa bernama seperti berikut:

mknod myPipe p

Dan saya membacanya dari beberapa proses (misalnya, beberapa server). Sebagai contoh, saya menggunakan ekor:

tail -f myPipe

Jika beberapa proses klien menulis beberapa pesan ke dalamnya (misalnya echo "msg" >> myPipe,, apakah ada kemungkinan pesan akan disisipkan, seperti ini:

 <beginning of message1><message2><ending of message1>

Atau apakah proses penulisan pipa bernama itu atomik?

Rogach
sumber

Jawaban:

29

Tergantung pada seberapa banyak setiap proses menulis (dengan asumsi OS Anda adalah POSIX-compliant dalam hal ini). Dari write():

Menulis permintaan ke pipa atau FIFO akan ditangani dengan cara yang sama seperti file biasa dengan pengecualian berikut:
[...]

  • Permintaan menulis sebesar {PIPE_BUF} byte atau kurang tidak boleh disisipkan dengan data dari proses lain yang melakukan penulisan pada pipa yang sama. Tulisan yang lebih besar dari {PIPE_BUF} byte mungkin memiliki data yang disisipkan, pada batas yang sewenang-wenang, dengan penulisan oleh proses lain, apakah bendera O_NONBLOCK dari bendera status file ditetapkan atau tidak.

Juga di Dasar Pemikiran bagian mengenai pipa dan FIFOs:

  • Atom / non-atom : Tulis adalah atom jika seluruh jumlah yang ditulis dalam satu operasi tidak disatukan dengan data dari proses lain. Ini berguna ketika ada banyak penulis mengirim data ke satu pembaca. Aplikasi perlu tahu seberapa besar permintaan penulisan dapat dilakukan secara atom. Maksimum ini disebut {PIPE_BUF}. Volume POSIX.1-2008 ini tidak mengatakan apakah permintaan tulis untuk lebih dari {PIPE_BUF} byte adalah atomik, tetapi mengharuskan penulisan {PIPE_BUF} atau lebih sedikit byte akan bersifat atomik.

Nilai jika PIPE_BUFditentukan oleh setiap implementasi, tetapi minimum adalah 512 byte (lihat limits.h). Di Linux, ini adalah 4096 byte (lihat pipe(7)).

Tikar
sumber
5
Omong-omong, PIPE_BUF dijamin setidaknya 512. Perhatikan bahwa Anda juga harus menjamin bahwa proses Anda benar-benar menulis setiap baris ke sana dalam satu panggilan tulis. Mengaktifkan penyangga baris ( setvbuf(stdout, NULL, _IOLBF,512)) akan melakukan ini tanpa mengharuskan Anda untuk menggunakan fungsi tingkat rendah.
Random832
Berikut adalah tabel PIPE_BUFnilai yang diamati pada sistem Unix yang umum: ar.to/notes/posix#pipe-buf
Arto Bendiken
Saya tidak mengerti bagaimana soket bisa multiplexed ... tetapi pipa bernama tidak bisa ?? semuanya di unix hanyalah sebuah file bukan? lulz
Alexander Mills
@AlexanderMills: Saya tidak mengerti komentar Anda
Mat
1
@AlexanderMills: tidak, itu nilai minimum
Mat