Python 进程挂起,直到子进程使用 tee 方案终止

发布于 2024-11-02 10:23:09 字数 1357 浏览 5 评论 0原文

我有以下与进程同步相关的问题。

有一个Python脚本startup.py、一个可执行的maestro和一个可执行的tee。 我的Python脚本startup.py启动maestro程序,并使用tee将maestro的stderr/stdout通过管道传输到日志文件中,并写入控制台。

我使用以下代码实现了这一点:

cmd = "maestro"
mae_err_log = "output.txt"
maestro = subprocess.Popen(cmd, stderr = subprocess.STDOUT, stdout=subprocess.PIPE)
tee = subprocess.Popen(['tee', mae_err_log], stdin = maestro.stdout)
maestro.stdout.close()
tee.communicate()
maestro_status = maestro.returncode
sys.exit(maestro_status)

我的 maestro 程序是一个 gui 程序,当我退出 maestro 程序时,它在内部调用 posix system("maestro_cleanup &") api 并立即退出。我注意到,尽管我在后台运行 maestro_cleanup,但在 maestro_cleanup 程序终止之前,我的 maestro 程序不会释放控制台。我需要在后台运行 maestro_cleanup,因为这需要时间,并且我不想在 maestro_cleanup 完成之前保持控制台。使用上面的代码,maestro 程序在 maestro_cleanup 完成之前不会终止。

我看到“ps -elf”显示如下:

0 S j 16876  6678  0  75 0 - 65307 wait 18:56 pts/53 00:00:00 python startup.py
0 Z j 17230 16876  4  76 0 - 0     exit 18:56 pts/53 00:00:04 [maestro] <defunct>
0 S j 17231 16876  0  77 0 - 948 pipe_w 18:56 pts/53 00:00:00 /usr/bin/tee output.txt
0 S j 17424     1  0  77   0 -   948 -  18:57 pts/53   00:00:00 maestro_cleanup

您可以看到 maestro_cleanup 父进程是会话进程 id 而不是 maestro,因为我在后台使用系统 api 启动了 maestro_cleanup。

知道为什么 maestro 在 maestro_cleanup 完成之前不会终止吗?

任何帮助将不胜感激。

-维宾

I have a following problem related to process synchronization.

There is a python script startup.py, an executable maestro, and an executable tee.
My python script startup.py starts maestro program and pipes the stderr/stdout of maestro into the log file using tee as well write into the console.

I achieved this using following code:

cmd = "maestro"
mae_err_log = "output.txt"
maestro = subprocess.Popen(cmd, stderr = subprocess.STDOUT, stdout=subprocess.PIPE)
tee = subprocess.Popen(['tee', mae_err_log], stdin = maestro.stdout)
maestro.stdout.close()
tee.communicate()
maestro_status = maestro.returncode
sys.exit(maestro_status)

My maestro program is a gui program when I exit from the maestro program, it internally call posix system("maestro_cleanup &") api and immediately exit. I noticed that my maestro program does not release the console until maestro_cleanup program terminate although I am running maestro_cleanup in the background. I need to run maestro_cleanup in the background as it takes time and I do not want to hold the console for the period until maestro_cleanup finishes. Using above code, maestro program does not terminate until maestro_cleanup finishes.

I see "ps -elf" shows following:

0 S j 16876  6678  0  75 0 - 65307 wait 18:56 pts/53 00:00:00 python startup.py
0 Z j 17230 16876  4  76 0 - 0     exit 18:56 pts/53 00:00:04 [maestro] <defunct>
0 S j 17231 16876  0  77 0 - 948 pipe_w 18:56 pts/53 00:00:00 /usr/bin/tee output.txt
0 S j 17424     1  0  77   0 -   948 -  18:57 pts/53   00:00:00 maestro_cleanup

You can see the maestro_cleanup parent process is session process id instead maestro because I started maestro_cleanup using system api in background.

Any idea why maestro does not terminate until maestro_cleanup finishes?

Any help would be appreciated.

-Vipin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心碎的声音 2024-11-09 10:23:09

那么 subprocess.Popen 文档 确实说 tee.communicate() 将“等待进程终止”;您的调用也与 这个人确实说他的子进程在后台运行,所以看起来没问题。所以这种退出前阻塞听起来像是子进程的限制。

尝试 'Python 生成子子进程,分离,并退出',它引用了 ActiveState 配方:'以 Python 方式创建守护程序':将进程与控制终端分离并在后台作为守护程序运行的 Python 方法。

Well the subprocess.Popen documentation does say tee.communicate() will "Wait for process to terminate"; also your invocation is the same as this guy who does say his child process runs in the background, so that seems ok. So this blocking-before-exit sounds like a limitation of subprocess.

Try the links in 'Python spawn off a child subprocess, detach, and exit' which references the ActiveState recipe: 'Creating a daemon the Python way': The Python way to detach a process from the controlling terminal and run it in the background as a daemon.

(り薆情海 2024-11-09 10:23:09

我会说使用close_fd=True。它应该可以解决问题。

I'd say use close_fd=True. It should do the trick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文