读取超时和管道原子性的边缘条件是什么?

时间:2019-03-26 19:53:46

标签: bash pipe

内置的bash coproc允许我们异步运行命令并从命令的输出中读取命令(并根据需要写入命令的输入),但是在某些情况下,我不理解从管道中读取消息。

在检查协处理器的输出之前,我们需要谨慎处理协处理器退出的情况,因此让我们将其包装在可以等待我们读取的子外壳中:

孩子

#!/bin/bash
sleep 5
echo OK

父母

#!/bin/bash

# use "read" to basically wait forever
coproc ( ./child.sh; read )

while true; do
    if read -t .01 -u ${COPROC[0]} VAR; then
        echo "VAR=$VAR"
        break
    else
        echo "Waiting..."   
        sleep 1
    fi
done

一切似乎都很好。 运行并最终产生输出。 父级会定期尝试以较短的超时时间进行读取,并在读取失败时等待。最终读取成功,我们完成了。

除了:如果read -t .01在读取过程中途超时怎么办?对于联机帮助页,可能会失败,并且任何部分读取的数据都将保存在VAR中。 (为争辩起见,假设它存储O。)

  1. 在整个循环的下一次迭代中会发生什么?

    • 我们将能够收集其余数据(例如K\n)吗?
    • 我们会重新阅读整行(OK\n)吗?
    • 还是那条线的其余部分丢失了?

写到管道上的内容大概是原子大小小于一定的原子。而且我想如果有太多数据等待读取,它们将阻塞。如果父母在孩子开始写之前进行了部分读取,那会发生什么?

  1. 我们对父母的read有什么保证吗?
     child                  parent

situation 1 (obvious):

  1. writes
                         2. reads

situation 2 (obvious):

                         1. starts read
                         2. read timeout
  3. writes

situation 3:

  1. starts writing
                         2. starts read
                         3. read timeout?
  4. finishes writing

situation 4:

  1. starts writing
                         2. starts read
  3. finishes writing
                         4. read timeout?

situation 5:

                         1. starts read
  2. starts writing
                         3. read timeout?
  4. finishes writing

situation 6:

                         1. starts read
  2. writes
                         3. read timeout?

0 个答案:

没有答案