GNU/Linux >> Belajar Linux >  >> Linux

Seberapa Besar Buffer Pipa?

Sebagai komentar di saya bingung mengapa “| true" di makefile memiliki efek yang sama dengan "|| benar” tulis pengguna cjm:

Alasan lain untuk menghindari | true adalah bahwa jika perintah menghasilkan output yang cukup untuk mengisi buffer pipa, itu akan memblokir menunggu true untuk membacanya.

Apakah kami memiliki cara untuk mengetahui ukuran buffer pipa?

Jawaban yang Diterima:

Kapasitas buffer pipa bervariasi di seluruh sistem (dan bahkan dapat bervariasi pada sistem yang sama). Saya tidak yakin ada cara cepat, mudah, dan lintas platform untuk hanya mencari kapasitas pipa.

Mac OS X, misalnya, menggunakan kapasitas 16384 byte secara default, tetapi dapat beralih ke kapasitas 65336 byte jika penulisan besar dilakukan ke pipa, atau akan beralih ke kapasitas satu halaman sistem jika sudah terlalu banyak memori kernel sedang digunakan oleh buffer pipa (lihat xnu/bsd/sys/pipe.h , dan xnu/bsd/kern/sys_pipe.c; karena ini dari FreeBSD, perilaku yang sama juga dapat terjadi di sana).

Satu Linux pipa(7) halaman manual mengatakan bahwa kapasitas pipa adalah 65536 byte sejak Linux 2.6.11 dan satu halaman sistem sebelumnya (mis. 4096 byte pada sistem x86 (32-bit)). Kode (include/linux/pipe_fs_i.h , dan fs/pipe.c ) tampaknya menggunakan 16 halaman sistem (yaitu 64 KiB jika halaman sistem adalah 4 KiB), tetapi buffer untuk setiap pipa dapat disesuaikan melalui fcntl pada pipa (hingga kapasitas maksimum yang defaultnya adalah 1048576 byte, tetapi dapat diubah melalui /proc/sys/fs/pipe-max-size )).

Ini sedikit bash /perl kombinasi yang saya gunakan untuk menguji kapasitas pipa di sistem saya:

#!/bin/bash
test $# -ge 1 || { echo "usage: $0 write-size [wait-time]"; exit 1; }
test $# -ge 2 || set -- "[email protected]" 1
bytes_written=$(
{
    exec 3>&1
    {
        perl -e '
            $size = $ARGV[0];
            $block = q(a) x $size;
            $num_written = 0;
            sub report { print STDERR $num_written * $size, qq(n); }
            report; while (defined syswrite STDOUT, $block) {
                $num_written++; report;
            }
        ' "$1" 2>&3
    } | (sleep "$2"; exec 0<&-);
} | tail -1
)
printf "write size: %10d; bytes successfully before error: %dn" 
    "$1" "$bytes_written"

Inilah yang saya temukan saat menjalankannya dengan berbagai ukuran penulisan pada sistem Mac OS X 10.6.7 (perhatikan perubahan untuk penulisan yang lebih besar dari 16KiB):

% /bin/bash -c 'for p in {0..18}; do /tmp/ts.sh $((2 ** $p)) 0.5; done'
write size:          1; bytes successfully before error: 16384
write size:          2; bytes successfully before error: 16384
write size:          4; bytes successfully before error: 16384
write size:          8; bytes successfully before error: 16384
write size:         16; bytes successfully before error: 16384
write size:         32; bytes successfully before error: 16384
write size:         64; bytes successfully before error: 16384
write size:        128; bytes successfully before error: 16384
write size:        256; bytes successfully before error: 16384
write size:        512; bytes successfully before error: 16384
write size:       1024; bytes successfully before error: 16384
write size:       2048; bytes successfully before error: 16384
write size:       4096; bytes successfully before error: 16384
write size:       8192; bytes successfully before error: 16384
write size:      16384; bytes successfully before error: 16384
write size:      32768; bytes successfully before error: 65536
write size:      65536; bytes successfully before error: 65536
write size:     131072; bytes successfully before error: 0
write size:     262144; bytes successfully before error: 0

Skrip yang sama di Linux 3.19:

/bin/bash -c 'for p in {0..18}; do /tmp/ts.sh $((2 ** $p)) 0.5; done'
write size:          1; bytes successfully before error: 65536
write size:          2; bytes successfully before error: 65536
write size:          4; bytes successfully before error: 65536
write size:          8; bytes successfully before error: 65536
write size:         16; bytes successfully before error: 65536
write size:         32; bytes successfully before error: 65536
write size:         64; bytes successfully before error: 65536
write size:        128; bytes successfully before error: 65536
write size:        256; bytes successfully before error: 65536
write size:        512; bytes successfully before error: 65536
write size:       1024; bytes successfully before error: 65536
write size:       2048; bytes successfully before error: 65536
write size:       4096; bytes successfully before error: 65536
write size:       8192; bytes successfully before error: 65536
write size:      16384; bytes successfully before error: 65536
write size:      32768; bytes successfully before error: 65536
write size:      65536; bytes successfully before error: 65536
write size:     131072; bytes successfully before error: 0
write size:     262144; bytes successfully before error: 0

Catatan:PIPE_BUF nilai yang ditentukan dalam file header C (dan pathconf nilai untuk _PC_PIPE_BUF ), tidak menentukan kapasitas pipa, tetapi jumlah maksimum byte yang dapat ditulis secara atom (lihat POSIX write(2) ).

Terkait:Linux – gambar pipa ffmpeg diekstraksi dari video?

Kutipan dari include/linux/pipe_fs_i.h :

/* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
   memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */

Linux
  1. Cara menulis loop di Bash

  2. Bagaimana Cloud Membuat Analisis Big Data Lebih Efisien

  3. Bagaimana cara mem-pipe atau mengarahkan output dari curl -v?

  1. Bagaimana saya bisa memantau apa yang dimasukkan ke dalam buffer keluar standar dan pecah ketika string tertentu disimpan di dalam pipa?

  2. Cara mem-pipe hasil 'find' ke mv di Linux

  3. RAM 8G dan SSD - seberapa besar seharusnya swap?

  1. Bagaimana cara menghitung jumlah byte dalam sebuah file, mengelompokkan byte yang sama?

  2. Bagaimana cara menyalurkan sesuatu ke output audio?

  3. Seberapa besar seharusnya partisi swap?