Linux中的管道会丢失数据吗?

Linux中的管道会丢失数据吗?,linux,posix,pipe,Linux,Posix,Pipe,它能包含多少数据有上限吗?除非机器崩溃,否则它不会丢失数据。但是,很容易误用它并认为您正在丢失数据,这可能是因为写入操作未能写入您请求的所有数据,并且您没有检查返回值,或者您的读取操作出错 它所能保存的最大数据量取决于系统——如果您尝试写入的数据超过这个数量,您将得到一个短的写入,或者写入程序将阻塞,直到空间可用为止。pipe(7)手册页包含许多关于管道的有用信息,包括(至少在Linux上)缓冲区有多大。Linux有4K或64K的缓冲区,具体取决于版本 编辑 Tim提到了SIGPIPE,这也是一

它能包含多少数据有上限吗?

除非机器崩溃,否则它不会丢失数据。但是,很容易误用它并认为您正在丢失数据,这可能是因为写入操作未能写入您请求的所有数据,并且您没有检查返回值,或者您的读取操作出错

它所能保存的最大数据量取决于系统——如果您尝试写入的数据超过这个数量,您将得到一个短的写入,或者写入程序将阻塞,直到空间可用为止。
pipe(7)
手册页包含许多关于管道的有用信息,包括(至少在Linux上)缓冲区有多大。Linux有4K或64K的缓冲区,具体取决于版本

编辑

Tim提到了SIGPIPE,这也是一个可能导致数据丢失的潜在问题。如果读卡器在读取管道中的所有内容之前关闭管道,则未读数据将被丢弃,写入器在写入更多内容或关闭管道时将收到SIGPIPE信号,表明发生了这种情况。如果他们阻止或忽略信号管,他们将得到一个EPIPE错误。这包括保罗提到的情况


PIPE\u BUF
是一个常数,它告诉您对缓冲区的原子写入的限制。任何写入此大小或更小的文件都将完全成功或阻塞,直到完全成功为止(如果管道处于非阻塞模式,则给出eWoldBlock/EAGAIN)。它与内核管道缓冲区的实际大小没有关系,尽管很明显,缓冲区的大小必须至少为管道大小,以满足原子性保证。

如果您指的是在shell中使用
操作符,那么不,它不会丢失数据。它只是将左侧标准输出流上的应用程序连接到右侧标准输入流上的应用程序。如果您在应用程序之间传输数据,但没有得到预期的结果,尝试使用
将第一个应用程序的标准输出重定向到一个文件,然后使用
不会丢失数据的原因是,当与管道相关联的缓冲区填满时,对
写入的调用将阻塞,直到读卡器清空缓冲区足以完成操作为止。(您也可以进行非阻塞写入,但您有责任确保完成任何可能被阻塞的写入。)

您的管道不会丢失数据。如果应用程序中的数据丢失,请尝试使用gdb进行调试。 有几件事需要注意:
1) 您的缓冲区是否足够大以容纳您正在读取的所有数据
2) 检查管道上read()的返回码是否有错误
3) 您确定要将所有数据写入管道吗

4) 您的写/读操作是否被信号中断?ie:SIGPIPE?

发生以下情况时,管道中的数据可能会丢失:

  • 进程(写入程序)将n字节的数据写入管道,其中n≤<代码>管道\u BUF
  • 。这种写入保证是原子的,不会阻塞
  • 一个进程(读卡器)只读取MIT lose而不是lose。松散的是松散的tooth@intuited:坏分隔符“)”(缺少左括号)让我很开心,又多了4个字符:)加载这一个后,我实际上放弃了我的答案。你可能想提到SIGPIPE,可能有一种情况,你杀死了作者或读者,因此作者认为它写了一些读者没有读过的东西?PIPE_BUF in limits.h会告诉你限制有多大。带有_PC_PIPE_BUF的sysconf()可以在运行时告诉您(无论如何,在linux上)这不应该是FIONREAD吗?注意:在Linux上,至少FIONREAD表示写入描述符上有多少数据未读(例如stdout),但似乎并不表示读卡器已经离开。对我来说,如果有一种模式,让内核向编写器发送一个SIGPIPE,如果阅读器没有读取所有数据就离开了。谢谢,修正了输入错误。实际上,
    FIONREAD
    并不表示读取器是否已离开,因此需要定义一个超时。是的,如果发送了
    SIGPIPE
    ,我也会发现它很有用。