Linux 是否每个创建的管道都使用完整的64K?

Linux 是否每个创建的管道都使用完整的64K?,linux,buffer,pipe,Linux,Buffer,Pipe,如何实现管道重新缓冲?我可能会创建许多管道,但一次只能通过它们发送/接收几个字节,所以我不想不必要地浪费内存 编辑:我了解缓冲是什么,我问的是如何在Linux管道中具体实现缓冲,即是否在不考虑highwatermark的情况下分配完整的64K?缓冲区用于抵消生产者和消费者之间的速度差。如果您没有缓冲区,则必须在生成每个字节后切换任务,这将是非常低效的,因为上下文切换、数据和代码缓存的成本永远不会变热等。如果您的消费者生成数据的速度与生产者消耗数据的速度一样快,则您的缓冲区使用率通常会很低(但请继

如何实现管道重新缓冲?我可能会创建许多管道,但一次只能通过它们发送/接收几个字节,所以我不想不必要地浪费内存


编辑:我了解缓冲是什么,我问的是如何在Linux管道中具体实现缓冲,即是否在不考虑highwatermark的情况下分配完整的64K?

缓冲区用于抵消生产者和消费者之间的速度差。如果您没有缓冲区,则必须在生成每个字节后切换任务,这将是非常低效的,因为上下文切换、数据和代码缓存的成本永远不会变热等。如果您的消费者生成数据的速度与生产者消耗数据的速度一样快,则您的缓冲区使用率通常会很低(但请继续读取)。如果生产者比消费者快得多,缓冲区将完全填满,生产者将被迫等待,直到有更多的空间可用。慢生产者和快消费者的相反情况将在大部分时间使用非常小的缓冲区

使用情况还取决于您的两个进程是否实际并行运行(例如,在单独的内核上),或者它们是否共享一个内核,并且仅仅是由于操作系统的进程管理被愚弄到认为它们是并发的。如果您具有真正的并发性(独立的核心/CPU),那么您的缓冲区通常使用较少

无论如何,如果您的应用程序生成的数据不多,并且它们的速度相似,那么大部分时间缓冲区都不会很满。然而,如果在操作系统级别,以任何方式分配完整的64KB,我也不会感到惊讶。但是,除非您使用的是嵌入式设备,否则64KB并不多,因此即使始终允许最大大小,我也不会担心

顺便说一句,修改管道缓冲区的大小并不容易,例如,我们建议了一些技巧,但它们实际上是变通方法,用于修改缓冲区中数据的使用方式,而不是修改实际的缓冲区大小。您可以查看
ulimit-p
,但我不能100%确定它是否能为您提供所需的控制


编辑:查看Linux代码,看起来缓冲区确实改变了大小。不过,缓冲区的最小大小是一整页,所以若您只需要几个字节,那个么就会有浪费。我现在还不确定,但是一些使用
管道定义缓冲区的代码是16,提供64 kB的4 kB页面,这让我想知道缓冲区是否可以降到64 kB以下(最小1页可能只是一个额外的限制)。

感谢您的回复。不幸的是,我在嵌入式设备上运行,因此每根管道64K非常重要。因此,我需要明确知道,无论缓冲区的高水位线是什么,64K是否会被使用。我在Linux源代码中做了一个快速检查,并添加到了答案中。您可能需要更深入地了解它,但至少我们知道最小缓冲区大小至少是一页(可能更多),因此一些浪费是不可避免的。我的印象是,如果存在大量流量,Linux内核将增加缓冲区大小。这不是真的吗?@MattJoiner我想说网络缓冲区不同于管道缓冲区,部分原因是使用管道时,两个进程都在同一操作系统实例的控制下,而在网络连接上,通常只有一侧可以由操作系统控制。