有谁知道bash如何处理通过管道发送数据?
cat file.txt | tail -20
最佳答案
我决定写一个更详细的解释。
这里的“魔术”在于操作系统。与计算机上所有其他同时运行的进程(包括终端应用程序和内核)一样,这两个程序的确大致在同一时间启动,并在同一时间运行(操作系统在操作系统上分配它们的时间片)。 。因此,在传递任何数据之前,进程将进行必要的初始化。在您的示例中,tail正在解析'-20'参数,而cat正在解析'file.txt'参数并打开文件。在某个时刻,尾巴将到达需要输入的位置,并且将告诉操作系统它正在等待输入。在其他时间点(无论之前还是之后,都没关系),cat将开始使用stdout将数据传递到操作系统。这进入操作系统的缓冲区。 cat将某些数据放入缓冲区后,下一个尾部将在处理器上获得一个时间片,它将检索一些数据(或全部),这些数据将缓冲区留在操作系统上。当缓冲区为空时,尾部将不得不等待cat输出更多数据。如果cat输出数据的速度快于tail处理数据的速度,则缓冲区将扩展。 cat最终将完成数据的输出,但是tail将仍在处理中,因此cat将关闭并且tail将处理缓冲区中的所有剩余数据。当它们不再具有EOF的传入数据时,操作系统将发信号通知尾巴。尾巴将处理剩余的数据。在这种情况下,tail可能只是将所有数据接收到20行的循环缓冲区中,并且当操作系统通知它不再有传入的数据时,然后将最后的20行转储到其自己的stdout中,只是显示在终端中。由于tail是比cat更简单的程序,因此它可能会花费大部分时间等待cat将数据放入缓冲区。
在具有多个处理器的系统上,这两个程序将不仅在同一处理器内核上共享交替的时间片,而且可能在不同的内核上同时运行。
为了获得更多细节,如果您打开某种进程监视器(特定于操作系统),例如Linux中的“top”,您将看到正在运行的进程的完整列表,其中大多数进程实际上使用了0%的处理器。除非要处理数据,否则大多数应用程序会花费大部分时间不做任何事情。这很好,因为它允许其他进程根据其需要不受限制地访问处理器。这基本上是通过三种方式完成的。进程可以进入sleep(n)样式的指令,在该指令中,它基本上告诉内核等待n毫秒,然后再给它提供另一个工作时间片。通常,一个程序需要等待另一个程序的响应,例如“尾巴”等待更多数据进入缓冲区。在这种情况下,当有更多数据可用时,操作系统将唤醒该过程。最后,内核可以在执行过程中抢占一个进程,从而为其他进程提供一些处理器时间片。 “猫”和“尾巴”是简单的程序。在此示例中,tail花费大部分时间等待缓冲区中的更多数据,而cat花费大部分时间等待操作系统从硬盘驱动器中检索数据。瓶颈是文件存储所在物理介质的速度(或速度)。您可能会在第一次运行此命令时检测到的可感知的延迟是磁盘驱动器上的读取磁头搜索到硬盘驱动器上“file.txt”所在位置所花费的时间。如果您第二次运行该命令,则操作系统可能会将file.txt的内容缓存在内存中,并且您将不太可能看到任何明显的延迟(除非file.txt非常大,或者不再缓存该文件) )
您在计算机上执行的大多数操作都受IO约束,也就是说,您通常在等待数据来自硬盘驱动器或网络设备等。
关于linux - bash 管道处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19122/