我有一个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下(如果它可能有用)
答案 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),一个用于发送数据,另一个用于接收数据,并使用它们实现管道。 正如您之前发现的那样,其他解决方案是关于重新编译内核的方法,但我认为并非如此。
侨!