更改命名管道的缓冲区大小

更改命名管道的缓冲区大小

我听说对于命名管道,小于 512 字节的写入是原子的(写入不会交错)。

有没有办法增加特定命名管道的数量?

就像是:

mkfifo mynamedpipe --buf=2500

据说这是完整的文档: http://www.gnu.org/software/coreutils/manual/html_node/mkfifo-invocable.html#mkfifo-inspiration

man mkfifo带我到那个页面。

答案1

文件fifo只是一种文件类型,当打开它进行读取和写入时,会像 pipeline() 系统调用一样实例化管道。

至少在 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

上面,我曾经perl发出过fcntl(),对(我的系统上的 1031)的值进行编码F_SETPIPE_SZ

答案2

不是改变,而是有一个具有相同效果的 bash shell 实现,通过替换 processus 来F_SETPIPE_SZ替换表达式,如下所示:(它将在运行时被文件描述符替换)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做吧。

这样做的缺点是需要多启动一个进程;优点是您可以自由地实现巨大的缓冲区大小。

相关内容