设置管道缓冲区大小

时间:2011-03-07 10:50:40

标签: c buffer pipe

我有一个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下(如果它可能有用)

3 个答案:

答案 0 :(得分:14)

由于您提到您在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)

答案 1 :(得分:3)

我用Google搜索“linux pipe buffer size”并得到this as the top link。基本上,限制是64Kb并且是硬编码的。

编辑链接已经死了,无论如何它可能都是错误的。 Linux pipe(7)手册页说明了这一点:

  

管道容量有限。如果管道已满,则写入(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 :(得分:2)

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

侨!