Ubuntu 和 Debian 之间的管道大小不同

Different pipe size between Ubuntu and Debian

我正在用 OpenBSD netcat 测试文件传输,发现在 Ubuntu 而不是 Debian 上传输相同的文件需要更多的时间。使用 strace,我发现数据在 Ubuntu.

上以 64k 块的形式传输
mgamal@ubuntu:~$ strace cat test | nc -vvvv 10.10.172.11 8888
...

read(3, "[=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=]"..., 65536) = 65536

write(1, "[=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=]"..., 65536) = 65536

read(3, "[=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=]"..., 65536) = 65536

write(1, "[=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=]"..., 65536) = 65536

read(3, "[=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=]"..., 65536) = 65536

write(1, "[=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=][=11=]"..., 65536) = 65536

另一方面,在 Debian 上:

mgamal@ubuntu:~$ strace cat test | nc -vvvv 10.10.172.11 8888
....
write(1, "[=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=]"..., 131072) = 131072
read(3, "[=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=]"..., 131072) = 131072
write(1, "[=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=]"..., 131072) = 131072
read(3, "[=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=]"..., 131072) = 131072
write(1, "[=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=][=12=]"..., 131072) = 131072

我在 Debian 上写了以下代码来检查管道大小:

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

int main()
{
    int pipefd[2];
    int size;
    int i;

    pipefd[0] = STDIN_FILENO;
    pipefd[1] = STDOUT_FILENO;

    pipe(pipefd);

    size = fcntl(pipefd[0], F_GETPIPE_SZ);

    printf("%d\n", size);

    size = fcntl(pipefd[1], F_GETPIPE_SZ);

    printf("%d\n", size);

    return 0;
 }

运行它,还是报64k

mgamal@debian:~$ ./test
65536
65536

我也试过使用 netcat 以外的东西来检查。我仍然看到管道尺寸为 128k

root@debian:~# strace cat foo | less
...
read(3, "[=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=]"..., 131072) = 131072
write(1, "[=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=]"..., 131072) = 131072
read(3, "[=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=]"..., 131072) = 131072
write(1, "[=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=]"..., 131072) = 131072
read(3, "[=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=]"..., 131072) = 131072
write(1, "[=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=]"..., 131072) = 131072
read(3, "[=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=]"..., 131072) = 131072

我已经尝试检查 netcat、内核、glibc 的源包以查看管道大小是否设置为 128k,或者是否有任何对 fcntl() 的调用改变了管道大小,但可能找不到踪迹。

为什么报告的管道尺寸为 64k,而实际尺寸为 128k?

GNU cat 在 coreutils 包中。 GNU cat 在其输入和输出上执行 statfstat 并查看 st_blksize,文件系统的最佳块大小 I/O。然后它采用该数字的最大值和硬连线数字,并将其用作输入和输出的缓冲区大小。这是在 io_blksize.

中完成的

Ubuntu 14 随 coreutils 8.21 一起提供。 that version 中的最小块大小为 64KiB。

Debian 8 附带 coreutils 8.23。 that version 中的最小块大小为 128KiB。