【问题标题】:Set pipe buffer size设置管道缓冲区大小
【发布时间】:2011-07-10 06:39:47
【问题描述】:

我有一个 C++ 多线程应用程序,它使用 posix 管道来有效地执行线程间通信(所以我不必为死锁而发疯)。

我已将写入操作设置为非阻塞,因此如果缓冲区中没有足够的空间进行写入,写入器会出错。

if((pipe(pipe_des)) == -1)
    throw PipeException();

int flags = fcntl(pipe_des[1], F_GETFL, 0); // set write operation non-blocking
assert(flags != -1);
fcntl(pipe_des[1], F_SETFL, flags | O_NONBLOCK);

现在我希望将管道缓冲区大小设置为自定义值(在特定情况下为一个字)。

我已经用谷歌搜索了它,但我找不到任何有用的东西。有办法(可能符合 posix)吗?

谢谢

洛伦佐

PS:我在linux下(如果有用的话)

【问题讨论】:

  • 这是对 assert() 的完全不当使用,除非你的程序只在 fcntl() 永远不会出错的平台上运行。
  • 我认为你应该学习如何使用同步原语。使用管道会增加大约 100 倍的开销,而且似乎无论如何也达不到你想要的效果。
  • 我知道如何使用同步原语 :) 实际上我也有一个使用同步原语的版本...查看测试结果,带有管道的版本至少比同步版本更快(在某些情况下)案例管道速度更快...)
  • 您可以使用 unix 套接字对来代替管道。 setsockopt(fd, SOL_SOCKET, SO_SNFBUF, size) 是要设置缓冲区大小的调用。

标签: c buffer pipe


【解决方案1】:

我用谷歌搜索了“linux 管道缓冲区大小”并得到了this as the top link。基本上,限制是 64Kb 并且是硬编码的。

编辑链接已失效,而且很可能是错误的。 Linux pipe(7) 手册页这样说:

管道的容量有限。如果管道已满,则 write(2) 将阻塞或失败,取决于是否设置了 O_NONBLOCK 标志 (见下文)。不同的实现有不同的限制 管道容量。应用程序不应依赖于特定的 容量:一个应用程序应该被设计成一个读取过程 在数据可用时立即使用数据,以便写入过程 不会一直被阻止。

在2.6.11之前的Linux版本中,管道的容量是一样的 作为系统页面大小(例如,i386 上的 4096 字节)。由于Linux 2.6.11,管道容量为16页(即一个系统中65,536字节 页面大小为 4096 字节)。自 Linux 2.6.35 起,默认 管道容量为16页,但容量可查询和设置 使用 fcntl(2) F_GETPIPE_SZ 和 F_SETPIPE_SZ 操作。看 fcntl(2) 了解更多信息。

无论如何,以下内容仍然适用于 IMO:

我不确定您为什么要尝试将限制设置得更低,这对我来说似乎是一个奇怪的想法。如果你想让作者等到读者处理完它写的东西,你应该使用另一个方向的管道让读者发回一个确认。

【讨论】:

  • 我正在通过管道发送任务。我想要的是有一个异步程度,可以通过传递给应用程序的参数进行配置。我认为在不跟踪其他信息和确认的情况下将此行为合并到管道中应该是一种有效的解决方案......
  • 底线是你不能按照你想要的方式去做。
  • 链接已失效
【解决方案2】:

您可以使用两个词的共享内存区域(类似 System V),一个用于发送数据,另一个用于接收数据,并使用它们实现您的管道。 正如您之前可能发现的那样,其他解决方案是根据您的需要重新编译内核,但我想并非如此。

Ciao!

【讨论】:

    【解决方案3】:

    由于您提到您在 Linux 上并且可能不介意不可移植性,因此您可能对文件描述符操纵器 F_SETPIPE_SZ 感兴趣,自 Linux 2.6.35 起可用。

    int pipe_sz = fcntl(pipe_des[1], F_SETPIPE_SZ, sizeof(size_t));
    

    在调用之后你会发现pipe_sz == getpagesize(),因为缓冲区不能小于系统页面大小。见fcntl(2)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多