名前付きパイプの場合、512バイト未満の書き込みはアトミックであると聞きました(書き込みはインターリーブされません)。
特定の名前付きパイプの数を増やす方法はありますか?
それは次のとおりです。
mkfifo mynamedpipe --buf=2500
これは完全な文書と呼ばれます: http://www.gnu.org/software/coreutils/manual/html_node/mkfifo-invocable.html#mkfifo-inspiration
man mkfifo
そのページに移動してください。
答え1
ファイルはfifo
単純なファイル形式であり、読み取りと書き込みのために開くと、パイプライン()システムコールのようにパイプがインスタンス化されます。
少なくともLinuxでは、このパイプを介して転送されたデータはファイルシステムにまったく保存されません(カーネルメモリとしてカーネルにのみ保存されます)。しかもサイズfifo ファイルの属性は無関係で、常に 0 です。
Linuxでは、パイプバッファのサイズを変更できます(パイプがpipe()
インスタンス化を使用してインスタンス化されるか、fifoファイルを開いてパイプがインスタンス化されるか)F_SETPIPE_SZ
fcntl()
。ただし、権限のないユーザーには制約が適用されます/proc/sys/fs/pipe-max-size
。パイプの作成者やリーダーは誰でもこのコマンドを実行できますが、fcntl()
作成者がそれを行う方が合理的です。名前付きパイプの場合は、fifoファイルでインスタンス化された各パイプに対してこれを行う必要があります。
$ mkfifo fifo
$ exec 3<> fifo # instantiate the pipe
$ seq 20000 > fifo
^C # seq hangs because it's trying to write more than 64KiB
$ exec 3<&- 3<> fifo # close the first pipe and instantiate a new one
$ (perl -MFcntl -e 'fcntl(STDOUT, 1031, 1048576)'; seq 20000) > fifo
$ # went through this time
上記では(私のシステムでは1031)値をエンコードしてをperl
発行しました。 fcntl()
F_SETPIPE_SZ
答え2
変更する代わりに、processusをF_SETPIPE_SZ
次の式に置き換えることで、同じ効果を持つbashシェル実装があります。 (実行時にファイル記述子に置き換えられます)fifo
>(stdbuf -o100M grep -a '^' > fifo)
/dev/fd/63
mkfifo fifo
exec 3<> fifo
seq 12000000 > >(stdbuf -o100M grep -a '^' > fifo)
すべてのフィルタがバッファリングモードの変更に敏感であるわけではありませんstdbuf
。たとえば、単に使用することはできませんcat
。同じ理由で言うこともできませんstdbuf -o100M seq 12000000 > fifo
。私が知っている限り、sed
grep
ただawk
クラシックをしましょう。
欠点は、1つ以上のプロセスを開始する必要があることです。利点は、巨大なバッファサイズを自由に実装できることです。