Python 子进程在接收 stdin EOF 时遇到神秘延迟

2023-12-02

我将应用程序中遇到的问题简化为以下测试用例。在此代码中,父进程同时生成 2 个(您可以生成更多)子进程,这些子进程通过 stdin 从父进程读取一条大消息,休眠 5 秒,然后写回一些内容。然而,某处发生了意外的等待,导致代码在 10 秒内完成,而不是预期的 5 秒。

如果你设置verbose=True,您可以看到落后的子进程正在接收大部分消息,然后等待最后 3 个字符块——它没有检测到管道已关闭。此外,如果我对第二个过程不做任何事情(doreturn=True),第一个过程将never见EOF。

有什么想法发生了什么吗?再往下是一些示例输出。提前致谢。

from subprocess import *
from threading import *
from time import *
from traceback import *
import sys
verbose = False
doreturn = False
msg = (20*4096+3)*'a'
def elapsed(): return '%7.3f' % (time() - start)
if sys.argv[1:]:
  start = float(sys.argv[2])
  if verbose:
    for chunk in iter(lambda: sys.stdin.read(4096), ''):
      print >> sys.stderr, '..', time(), sys.argv[1], 'read', len(chunk)
  else:
    sys.stdin.read()
  print >> sys.stderr, elapsed(), '..', sys.argv[1], 'done reading'
  sleep(5)
  print msg
else:
  start = time()
  def go(i):
    print elapsed(), i, 'starting'
    p = Popen(['python','stuckproc.py',str(i), str(start)], stdin=PIPE, stdout=PIPE)
    if doreturn and i == 1: return
    print elapsed(), i, 'writing'
    p.stdin.write(msg)
    print elapsed(), i, 'closing'
    p.stdin.close()
    print elapsed(), i, 'reading'
    p.stdout.read()
    print elapsed(), i, 'done'
  ts = [Thread(target=go, args=(i,)) for i in xrange(2)]
  for t in ts: t.start()
  for t in ts: t.join()

输出示例:

  0.001 0 starting
  0.003 1 starting
  0.005 0 writing
  0.016 1 writing
  0.093 0 closing
  0.093 0 reading
  0.094 1 closing
  0.094 1 reading
  0.098 .. 1 done reading
  5.103 1 done
  5.108 .. 0 done reading
 10.113 0 done

我正在使用Python 2.6.5,如果这有什么区别的话。


经过太多时间后,我在引用了这个帖子向我跳出来:

请参阅 pipeline(7) 的“管道和 FIFO 上的 I/O”部分(“man 7 pipeline”)

“如果所有引用管道写入端的文件描述符都有 已关闭,然后尝试从管道读取(2)将看到 文件结尾(read(2) 将返回 0)。”

我应该知道这一点,但我从来没有想到过——与 Python 特别无关。发生的情况是:子进程通过打开(编写器)文件描述符到彼此的管道进行分叉。只要管道有打开的写入器文件描述符,读取器就不会看到 EOF。

E.g.:

p1=Popen(..., stdin=PIPE, ...) # creates a pipe the parent process can write to
p2=Popen(...) # inherits the writer FD - as long as p2 exists, p1 won't see EOF

原来有一个close_fds参数为Popen,所以解决方案是通过close_fds=True。事后看来,一切都简单明了,但仍然花费了至少几个眼球的大量时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 子进程在接收 stdin EOF 时遇到神秘延迟 的相关文章

  • 检测到通过 ChromeDriver 启动的 Chrome 浏览器

    我正在尝试在 python 中使用 selenium chromedriver 来访问 www mouser co uk 网站 然而 从第一次拍摄开始 它就被检测为机器人 有人对此有解释吗 此后我使用的代码 options Options
  • 在 python 3 中使用子进程

    我使用 subprocess 模块在 python 3 中运行 shell 命令 这是我的代码 import subprocess filename somename py in practical i m using a real fil
  • 从 Python 下载/安装 Windows 更新

    我正在编写一个脚本来自动安装 Windows 更新 我可以将其部署在多台计算机上 这样我就不必担心手动更新它们 我想用 Python 编写这个 但找不到任何关于如何完成此操作的信息 我需要知道如何搜索更新 下载更新并从 python 脚本安
  • 在Python中如何获取字典的部分视图?

    是否有可能获得部分视图dict在Python中类似于pandasdf tail df head 说你有很长一段时间dict 而您只想检查某些元素 开头 结尾等 dict 就像是 dict head 3 To see the first 3
  • Python 是解释型的还是编译型的,或者两者兼而有之?

    据我了解 An 解释的语言是由解释器 将高级语言转换为机器代码然后执行的程序 实时运行和执行的高级语言 它一次处理一点程序 A compiled语言是一种高级语言 其代码首先由编译器 将高级语言转换为机器代码的程序 转换为机器代码 然后由执
  • 使用 NLTK 在 Python 中获取大量名词(或形容词);或 Python Mad Libs

    Like 这个问题 https stackoverflow com questions 7439555 noun adjective etc word lists or dictionaries common words 我有兴趣按词性获取
  • 将二维数组放入 Pandas 系列中

    我有一个 2D Numpy 数组 我想将其放入 pandas 系列 而不是 DataFrame 中 gt gt gt import pandas as pd gt gt gt import numpy as np gt gt gt a np
  • 如何在Python中高效地添加稀疏矩阵

    我想知道如何在Python中有效地添加稀疏矩阵 我有一个程序 可以将大任务分解为子任务 并将它们分配到多个 CPU 上 每个子任务都会产生一个结果 一个 scipy 稀疏矩阵 格式为 lil matrix 稀疏矩阵尺寸为 100000x50
  • 根据 Pandas 中的列表对多列进行排序

    感谢有关如何根据 pandas 中的倍数列表对给定多列进行排序的任何提示 如下所示 import pandas as pd sort a a d e sort b s1 s3 s6 sort c t1 t2 t3 df pd DataFra
  • 将 numpy 代码点数组与字符串相互转换

    我有一个很长的 unicode 字符串 alphabet range 0x0FFF mystr join chr random choice alphabet for in range 100 mystr re sub W mystr 我想
  • ValueError:不支持连续[重复]

    这个问题在这里已经有答案了 我正在使用 GridSearchCV 进行线性回归的交叉验证 不是分类器也不是逻辑回归 我还使用 StandardScaler 对 X 进行标准化 我的数据框有 17 个特征 X 和 5 个目标 y 观察 约11
  • 在相同任务上,Keras 比 TensorFlow 慢

    我正在使用 Python 运行斩首 DCNN 本例中为 Inception V3 来获取图像特征 我使用的是 Anaconda Py3 6 和 Windows7 使用 TensorFlow 时 我将会话保存在变量中 感谢 jdehesa 并
  • 如何使用 Bokeh 动态隐藏字形和图例项

    我正在尝试在散景中实现复选框 其中每个复选框应显示 隐藏与其关联的行 我知道可以通过图例来实现这一点 但我希望这种效果同时在两个图中发生 此外 图例也应该更新 在下面的示例中 出现了复选框 但不执行任何操作 我显然不明白如何更新用作源的数据
  • 如何在 Django 中使用基于类的视图创建注册视图?

    当我开始使用 Django 时 我几乎使用 FBV 基于函数的视图 来处理所有事情 包括注册新用户 但当我更深入地研究项目时 我意识到基于类的视图通常更适合大型项目 因为它们更干净且可维护 但这并不是说 FBV 不是 无论如何 我将整个项目
  • 迭代列表的奇怪速度差异

    我创建了两个重复两个不同值的长列表 在第一个列表中 值交替出现 在第二个列表中 一个值出现在另一个值之前 a1 object object 10 6 a2 a1 2 a1 1 2 然后我迭代它们 不对它们执行任何操作 for in a1 p
  • 如何在 Azure 数据工厂 - Databricks 中使用 continuation_token 获取 ADF Pipeline 运行详细信息的下一页?

    我在用 adf client pipeline runs query by factory resourceGroupName 工厂名称 过滤器参数 的方法azure mgmt datafactory DataFactoryManageme
  • Python:我不明白 sum() 的完整用法

    当然 我明白你使用 sum 与几个数字 然后它总结所有 但我正在查看它的文档 我发现了这一点 sum iterable start 第二个参数 start 的作用是什么 这太尴尬了 但我似乎无法通过谷歌找到任何示例 并且对于尝试学习该语言的
  • 附加两个具有相同列、不同顺序的数据框

    我有两个熊猫数据框 noclickDF DataFrame 0 123 321 0 1543 432 columns click id location clickDF DataFrame 1 123 421 1 1543 436 colu
  • 从列表python的单个列表中删除子列表

    我已经经历过从列表列表中删除子列表 https stackoverflow com questions 47209786 removing sublists from a list of lists 但当我为我的数据集扩展它时 它不适用于我
  • bs4 `next_sibling` VS `find_next_sibling`

    我在使用时遇到困难next sibling 并且类似地与next element 如果用作属性 我不会得到任何返回 但如果用作find next sibling or find next 然后就可以了 来自doc https www cru

随机推荐