管道缓冲区大小是 4k 还是 64k?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4624071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:05:29  来源:igfitidea点击:

Pipe buffer size is 4k or 64k?

clinuxsizebufferpipe

提问by Gui13

I read in multiple places that the default buffer size for a pipe is 4kB (for instance, here), and my ulimit -atends to confirm that statement:

我在多个地方读到管道的默认缓冲区大小为 4kB(例如,这里),并且我ulimit -a倾向于确认该声明:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 15923
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8 // 8 * 512B = 4kB
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

But when I use a little program to test the buffer size (by writing into the pipe until the write() blocks), I see a limit of 64kB!

但是当我使用一个小程序来测试缓冲区大小(通过写入管道直到 write() 阻塞)时,我看到了 64kB 的限制!

See this program:

看这个节目:

#include <stdio.h>
#include <unistd.h>
#include <limits.h>

int main(void)
{
    int tube[2];
    char c = 'c';
    int i;

    fprintf(stdout, "Tube Creation\n");
    fprintf(stdout, "Theoretical max size: %d\n", PIPE_BUF);
    if( pipe(tube) != 0)
    {
        perror("pipe");
        _exit(1);
    }
    fprintf(stdout, "Writing in pipe\n");
    for(i=0;; i++)
    {
        fprintf(stdout, "%d bytes written\n", i+1);
        if( write(tube[1], &c, 1) != 1)
        {
            perror("Write");
            _exit(1);
        }
    }
    return 0;
}

And its output:

它的输出:

$ ./test_buf_pipe 
Tube Creation
Theoretical max size: 4096
Writing in pipe
1 bytes written
2 bytes written
3 bytes written
4 bytes written
[...]
65535 bytes written
[blocks here]

It strongly suggests that the pipe buffer size is actually 64k! What is happening here??

它强烈建议管道缓冲区大小实际上是 64k!这里发生了什么?

采纳答案by janneb

The other answers tell you that the pipe size is 64 KB. The reason why PIPE_BUF is 4KB is that PIPE_BUF is the largest size for which writes are guaranteed to be atomic. See http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

其他答案告诉您管道大小为 64 KB。PIPE_BUF 为 4KB 的原因是 PIPE_BUF 是保证写入是原子的最大大小。见http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

回答by nos

That's right. Since the 2.6.11 kernel, the pipesize in Linux is 64kB. Why ulimit reports it as 4Kb, I'm not sure, but that's wrong.

这是正确的。从 2.6.11 内核开始,Linux 中的管道大小为 64kB。为什么 ulimit 将其报告为 4Kb,我不确定,但这是错误的。

回答by shodanex

Looks like the kernel use up to 16 buffers which adds up to 64k. See this linkfor an explanation of the ulimit output vs actual buffer size

看起来内核最多使用 16 个缓冲区,总计 64k。有关ulimit 输出与实际缓冲区大小的说明,请参阅此链接

回答by user1380175

In my experience, the single write test produced a total size of 65536, yet when I wrote 2700 at a time, I could only write 16 times, and then the next attempt stalls. I figure that the 'atomic' write needs to be within one 4K block, and that for each of my writes, it goes to the next full block to satisfy the request. So, in effect, the useable pipe size depends on the size of your writes.

以我的经验,单次写测试产生的总大小为65536,而我一次写2700时,我只能写16次,然后下一次尝试就停滞了。我认为“原子”写入需要在一个 4K 块内,并且对于我的每次写入,它都会转到下一个完整块以满足请求。因此,实际上,可用的管道大小取决于写入的大小。

回答by DigitalRoss

It's programmable now

现在是可编程的



As of Linux 2.6.35 you can use fcntl(2)with the F_SETPIPE_SZoperation to set the pipe buffer up to /proc/sys/fs/pipe-max-size. This is by default 1 MB; see proc(5).

从 Linux 2.6.35 开始,您可以使用fcntl(2)F_SETPIPE_SZ操作将管道缓冲区设置为/proc/sys/fs/pipe-max-size. 默认为 1 MB;见过程(5)。