![为什么第二个命令不等待第一个命令(管道)的输出?](https://linux22.com/image/198501/%E4%B8%BA%E4%BB%80%E4%B9%88%E7%AC%AC%E4%BA%8C%E4%B8%AA%E5%91%BD%E4%BB%A4%E4%B8%8D%E7%AD%89%E5%BE%85%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%91%BD%E4%BB%A4%EF%BC%88%E7%AE%A1%E9%81%93%EF%BC%89%E7%9A%84%E8%BE%93%E5%87%BA%EF%BC%9F.png)
答案1
第二个命令可以在其输入尚未准备好的情况下开始执行。
确实如此。这没有什么问题。
在管道中producer | consumer
,两侧同时运行。消费者不会等待生产者完成。它甚至不关心生产者是否已经开始。消费者所需要的只是一个读取输入的地方。一旦调用创建了管道,这个地方就存在pipe
。
从管道读取是阻塞手术。如果尚未将数据写入管道,则读取器会阻塞。当数据写入管道时,读取器将被解除阻塞。更一般地,如果管道上没有可用数据,则读取器会阻塞。从管道读取数据会消耗它。因此,当消费者开始读取时,生产者是否已经开始写入并不重要。消费者将等待生产者写入一些数据。
消费者在数据可用时立即接收数据。²它通常以块的形式读取和处理数据。大多数消费者在开始处理之前不需要拥有所有数据。如果消费者确实需要所有可用数据,它会将其存储在内存或临时文件中,并等待输入结束。
由于生产者和消费者是独立的进程,因此它们是并发执行的。其中一个可能正在运行这一事实并不妨碍另一个运行。如果生产者和消费者都需要 CPU 时间,内核将在它们之间(以及任何其他需要 CPU 时间的进程之间)共享 CPU。因此,即使消费者正在初始化,或者正在处理一些数据,生产者也可以运行并产生更多数据。
1你可以说它们是并行运行的。这在技术上并不正确,但足够接近。
²在实践中,生产者可以缓冲内部数据。但一旦生产者实际将数据写入管道,消费者就可以读取它。