使用fifos/命名管道时的随机141信号

Random 141 Signals when working with fifos / named pipes

提问人:Philipp Lengauer 提问时间:10/8/2023 最后编辑:Philipp Lengauer 更新时间:10/8/2023 访问量:65

问:

我理解 fifos 的方式是,读取器或写入器的打开会阻塞,直到另一侧也打开,读取会阻塞直到有人写入,当另一侧的最后一个关闭时,任何一侧都会关闭,即最后一个写入器关闭,读者也关闭,反之亦然。

假设这是一个正确的基础,请告诉我:我有两个过程。一个是 bash 脚本,另一个是 python。bash 脚本在磁盘上创建一个 fifo,并在后台启动 python 脚本,并将 fifo 的名称作为参数。mkfifo

我的 python 进程有一个主循环,如下所示:

while True:
    with open(fifo_path, 'r') as fifo:
        for line in fifo:
            line = line.strip()
            if len(line) == 0:
                continue
            # code to handle line here ...

简化的 bash 脚本会这样做:

mkfifo test.pipe
python myscript.py test.pipe &
# code ...
echo "foo" > test.pipe
# more code
echo "bar" > test.pipe
# ...

根据我对管道的理解,应该会发生什么,读取 python 脚本将挂起,直到第一个回显(或者更具体地说是脚本)打开管道进行写入。然后他们将交换“foo”字符串,当回显完成时,管道被关闭,这将导致 python 脚本收到一个 EOF。但是,python脚本将继续,因为它的循环会再次打开,并且一切都会重复。

实际发生的情况是,有时我的 bash 脚本突然退出并显示退出代码 141。

我已经做了什么来调试它:

  1. 我验证了 python 进程确实正在运行并且没有崩溃。我已经打印了每个错误,并非常慷慨地添加了 尝试/排除块以确保我不会错过任何东西。
  2. 运行脚本似乎表明它确实是以代码 141 结尾的回声。bash -x
  3. 谷歌搜索和 Stackoverflowing 暗示我 141 是 SIGPIPE 的引擎盖下,似乎没有被处理。如果是这样的话,我 不明白它们为什么会发生以及我应该如何处理它们。 根据我上面的理解,它们不应该发生。
  4. 故意在 python 脚本开始时第二次打开 fifo 并故意泄漏 fd(从不读取它)

任何提示都是值得赞赏的。

Linux Bash IO 命名管道 mkfifo

评论

1赞 Philippe 10/8/2023
你说,有没有可能提供更多细节?你能发布一套完整的可重复的示例脚本吗?sometimes my bash script suddenly exits
1赞 rand'Chris 10/8/2023
这听起来很理智,除了 #4(从 python 打开 FIFO 两次)。python open 应该会成功并阻止,直到数据到达。为了让 bash 获得 SIGPIPE,python 可以在读取之前关闭 FIFO。你说你跑了 - 你能发布一个显示错误的跟踪吗?bash -x

答: 暂无答案