【问题标题】:How to run pexpect on waited process using multiprocessing?如何使用多处理在等待的进程上运行 pexpect?
【发布时间】:2021-12-05 21:55:10
【问题描述】:

我在 QNX 系统上运行 Python 2.7,我遇到了 pexpect 引发以下错误的问题:

ExceptionPexpect: isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?

这个错误的情况如下:我有两个文件,pexpectTest.pytestPexpectError.py

pexpectTest.py

导入多处理 导入预期 导入系统 pexp = pexpect.spawn('python testPexpectError.py') pexp.delaybeforesend = False pexp.logfile = sys.stdout 定义测试(): pexp.sendline('行') pexp.expect('>', timeout=None) pexp.close() mp = multiprocessing.Process(目标=测试) mp.start() mp.join()

testPexpectError.py

进口时间 而1: 输入 = raw_input(">") 打印输入 如果输入 == '退出': 休息 时间.sleep(1)

当从 multiprocessing.Process 调用时,本文顶部的异常会被抛出。 从主线程调用时,不会抛出异常。

我的主要问题是:

  1. 当从 multiprocessing.Process 调用期望与在主线程中调用期望时(如果这甚至是问题),是什么导致 pexpect 对 testPexpectError.py 中的等待调用做出反应?

  2. 有没有办法解决这个问题?

【问题讨论】:

  • 为什么要为此使用多处理?等待子进程写入输出不持有 GIL;您可以使用线程来以更低的开销实现相同的目标。
  • 基本上,您的直接问题是因为您生成的程序是试图读取其输出的进程的兄弟,而不是子进程。这意味着不可继承的文件描述符全部丢失在边界中,并且您不能使用wait syscall 系列来检索退出状态。
  • @CharlesDuffy 感谢您的意见。对于上下文:这只是我遇到的问题的一个超简化示例,我想了解更多。存在此问题的实际系统要复杂得多,因此它不能使用任何类型的线程,必须使用多处理。
  • 明白了。既然如此,我添加了一个涵盖“重组代码以使多处理工作”的答案,同时希望能比上述 cmets 更好地说明“为什么”。

标签: python python-2.7 multiprocessing pexpect qnx


【解决方案1】:

请记住,multiprocessing 的主要区别在于它在单独的进程中生成一个函数

文件描述符不跨进程边界共享(子进程可能会获得父进程 FD 的 副本,但这是一个可选的 per-FD 标志——参见描述 Python puts 接口的https://docs.python.org/3/library/os.html#fd-inheritance在该层之上)。

同样,父/子关系仅适用于原始父进程:您可以使用waitpid() 获取子进程,但不能获取兄弟进程(同一父进程的同伴子进程,这是您复制的@987654324 的关系@ 和 multiprocessing-spawned 子进程在这里)。

如果您真的需要在这里使用multiprocessing,请将spawn() 移动到您的test() 函数中,这样子进程的输出和退出状态就会被其父进程(而不是兄弟进程)读取,并且一切都会好起来的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多