【问题标题】:Why does Popen make the parent process hang on preexec_fn?为什么 Popen 会让父进程挂在 preexec_fn 上?
【发布时间】:2020-05-03 06:08:55
【问题描述】:

根据Python 3.6 docs for Popen

如果 preexec_fn 设置为可调用对象,则该对象将在子进程执行之前在子进程中调用。 (仅限 POSIX)

那为什么执行preexec_fn函数时父进程挂起呢?如果它在子进程中执行,那么父进程应该能够继续。

这是一个程序的小例子,它创建了一个新的“ls”进程,在此之前它会休眠 4 秒。理想情况下,应立即打印“到达”,但事实并非如此。 4 秒后打印“到达”。

import os
import subprocess
import sys
import tempfile
import time


def sleep_a_little():
    time.sleep(4)


p = subprocess.Popen(["ls"], preexec_fn=sleep_a_little)
print("reached")

【问题讨论】:

  • 可能是this
  • 嗯@Matt,它看起来不像,因为 Popen 不会永远挂起。链接的答案谈到了潜在的僵局。由于 preexec_fn 需要 4 秒来执行,它挂起 4 秒。我的问题是父进程不应该等待 preexec_fn 执行,因为这发生在子进程中。
  • 如果 preexec_fn 设置为可调用对象,则该对象将在子进程执行之前在子进程中调用。 (仅限 POSIX)。所以我认为应该先调用sleep_a_little,然后再调用ls,不是吗?
  • 是的,会在ls之前调用。但它是在 fork 之后调用的。所以子进程调用它。为什么父进程(原名为subprocess.Popen()的进程)在执行sleep_a_little时会挂在子进程上?

标签: python multiprocessing popen


【解决方案1】:

我遇到了类似的问题,但看起来正在发生的事情是 preexec_fn 函数只是由父级运行。

我的preexec_fn 使用os.setuidos.setgid 从特权父级启动用户进程。

在生成线程之前调用whoami 实用程序,然后在显示我的父级模拟用户帐户而不仅仅是它创建的子级之后再次调用。

【讨论】:

    猜你喜欢
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 2018-03-11
    相关资源
    最近更新 更多