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

时间:2016-02-09 13:15:52

标签: linux unix ubuntu debian pipe

我正在使用OpenBSD netcat测试文件传输,并注意到在Ubuntu而不是Debian上传输相同文件需要更多时间。使用strace,我发现数据在Ubuntu上以64k块传输。

mgamal@ubuntu:~$ strace cat test | nc -vvvv 10.10.172.11 8888
...

read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536

write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536

read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536

write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536

read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536

write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536

另一方面,在Debian上:

mgamal@ubuntu:~$ strace cat test | nc -vvvv 10.10.172.11 8888
....
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 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, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072) = 131072

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

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

1 个答案:

答案 0 :(得分:1)

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。