我们开发了一个python函数,该函数使用pdftoppm/pdftocairo启动子流程调用,以拆分pdf并将每个页面存储为单独的图像。假设一个文档是10页,它会创建10个单独的png文件,每个文件代表文档的页面。有没有一种方法可以使用htop
或ps -ef
命令拦截来自终端的进程?
如果您想要获取子流程时Python程序仍在运行,最简单的解决方案可能是将timeout
关键字参数传递给Popen.wait()
或Popen.communicate()
。
subprocs = []
for page in pdf.pages():
sub = subprocess.Popen(['pdftoppm', 'etc', '--page', str(page), filename])
subprocs.append(sub)
# some Python processing here while you wait for the subprocesses to run in the background?
# Then once you are done and only want to reap them before you continue
for sub in subprocs:
sub.wait(timeout=60)
当您对已经完成的子流程执行wait
时,调用会立即返回。当您对已经超过超时的子流程执行wait
时,也应该(大致(立即执行。因此,最后的for
循环应该有效地等待尚未完成或超过其超时的第一个子进程,然后迅速获得剩余的子进程
如果您的Python程序已经完成执行,并且还有一堆子进程在运行,那么您启动的子进程将是孤立的,它们将被重新排序为PID 1的子进程,因此您无法再检查父进程并查看它们是否属于您。如果它们都运行在一个特定的目录中,而没有其他进程在其中执行,那么这可能是隔离它们的好方法。(在subprocess.Popen()
中,您可以使用cwd=path_to_dir
传入目录。(在Linux上,/proc
文件系统使您可以轻松地遍历进程树并检查各个进程。进程树中的cwd
条目是指向进程运行目录的符号链接。
from pathlib import Path
for proc in Path('/proc').iterdir():
if all(x.isdigit() for x in proc.name):
if proc/'cwd'.readlink() == '/path/to/dir':
print(proc)
不幸的是,Path.readlink()
仅在Python 3.9中引入;如果您在使用旧Python版本的机器上需要此功能,请尝试更传统的os.path
意大利面条:
import os
for proc in os.listdir('/proc'):
if all(x.isdigit() for x in proc):
if os.readlink(os.path.join('/proc', proc, 'cwd')) == '/path/to/dir':
print(proc)
请注意,/proc
是不可移植的,但由于您特别询问Ubuntu,您应该能够使用这种方法。
如果您不想在特定的唯一目录中运行子流程,那么可能还有其他方法可以找到您的流程(如果它们是合理唯一的(,或者使它们合理唯一以便于实现这一点。您的问题并没有充分揭示您的代码或需求,从而不知道什么对您有效。
也许您可以使用一个外部timeout
命令来运行这些进程,并将其留在那里。GNU Coreutilstimeout
二进制文件是Ubuntu基本安装的一部分(但在其他一些类似U*x的系统上可能无法开箱即用(。
for page in pdf.pages():
subprocess.Popen(['timeout', '60', 'pdftoppm', 'etc', '--page', str(page), filename])
(上面显然对你正在运行的实际命令以及它需要的参数进行了疯狂的猜测。(
如果您实际上通过子流程模块运行流程,那么它应该显示为常规(子(流程,是的。
>>> from subprocess import run
>>> run('/usr/bin/cat')
将导致:
$ ps -u myuser
...
36456 pts/2 00:00:00 python3
36463 pts/2 00:00:00 cat
...