【问题标题】:Different pipe size between Ubuntu and DebianUbuntu和Debian之间的不同管道大小
【发布时间】:2016-02-09 13:15:52
【问题描述】:

我正在使用 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?

【问题讨论】:

  • 部分答案unix.stackexchange.com/questions/11946/…。 OSX 管道被报告为动态更改 big 写入的大小...您是否尝试在发送期间的不同时间获取大小?
  • 我在 Ubuntu 和 Debian 上都运行了答案中的脚本。两者都报告 64k,并且 0 字节写入超过 64k 的写入。
  • 我在 debian 中下载了 bash 源代码包,再次看到没有 fcntl() 调用。
  • 我还从程序中删除了 pipe() 调用。 Ran:date | ./test | tee foo 在 Debian 上仍然有 64k

标签: linux unix ubuntu debian pipe


【解决方案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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2014-10-24
    • 2014-09-07
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多