我目前正在阅读 M. Bach 的《UNIX\xc2\xae 操作系统的设计》。
\n我读到了有关主 shell 循环的内容。\n看看if (/* piping */)块。如果我理解正确的话,管道允许将第一个命令输出视为第二个命令输入。如果是这样,为什么没有代码让第二个命令等待第一个命令终止?如果没有这个命令,管道似乎毫无意义:第二个命令可以在其输入尚未准备好的情况下开始执行。
\n\n第二个命令可以在其输入尚未准备好的情况下开始执行。
\n
确实如此。这没有什么问题。
\n在管道中producer | consumer,两侧同时运行\xc2\xb9。消费者不会等待生产者完成。它甚至不关心生产者是否已经开始。消费者所需要的只是一个读取输入的地方。一旦管道被创建,这个地方就存在pipe。
从管道读取是阻塞的操作。如果尚未将数据写入管道,则读取器会阻塞。当数据写入管道时,读取器将被解除阻塞。更一般地,如果管道上没有可用数据,则读取器会阻塞。从管道读取数据会消耗它。因此,当消费者开始读取时,生产者是否已经开始写入并不重要。消费者将等待生产者写入一些数据。
\n消费者在数据可用时立即接收数据。\xc2\xb2 它通常以块的形式读取和处理数据。大多数消费者在开始处理之前不需要拥有所有数据。如果消费者确实需要所有可用数据,它将把它存储在内存或临时文件中,并等待输入结束。
\n由于生产者和消费者是独立的进程,因此它们是并发执行的。其中一个可能正在运行这一事实并不妨碍另一个运行。如果生产者和消费者都需要 CPU 时间,内核将在它们之间(以及任何其他需要 CPU 时间的进程之间)共享 CPU。因此,即使消费者正在初始化,或者正在处理一些数据,生产者也可以运行并产生更多数据。
\n\xc2\xb9你可以说它们是并行运行的。这在技术上并不正确,但足够接近。
\n\xc2\xb2实际上,生产者可以在内部缓冲数据。但一旦生产者实际将数据写入管道,消费者就可以读取它。