【无标题】

1. 需求

python主进程唤起一个python子进程,该子进程运行时会实时打印信息,主进程需要获得子进程的实时信息。

这里,需要区分两种情况:当子进程消息较少时,比如自己写的一个子进程,里面用print打印部分信息,此时不需要考虑缓存问题;当子进程消息较多且输出速度快,比如yolov5模型的训练,输出里面存在进度条显示,数据量较大且速度很快,此时需要考虑缓存问题。

主要参考博客《python如何启动新进程,并实时获取程序的输出.》和博客《python subprocess.Popen的使用》

2. 不考虑缓存情况下的实现

此种情况适用于子进程消息较少时,比如自己写的一个子进程,里面用print打印部分信息。
2.1. 子进程测试代码

该代码为子进程测试代码testSub.py,代码内用print进行输出。

python 复制代码
import time
i = 0
while (i<40):
    print("当前处于第{}秒".format(i))
    time.sleep(1)
    i += 1

2.2. 主进程代码

该代码为主进程代码testMain.py,用subprocess.popen运行子进程testSub.py,并获得子进程的实时打印结果。

python 复制代码
import subprocess
import threading

class CMDProcess(threading.Thread):
    '''
        执行CMD命令行的 进程
    '''
    def __init__(self, args,callback):
        threading.Thread.__init__(self)
        self.args = args
        self.callback=callback
        
    def run(self):
        self.proc = subprocess.Popen(
            self.args,
            bufsize=0,
            shell = False,
            stdout=subprocess.PIPE
        )
        
        while self.proc.poll() is None:
            line = self.proc.stdout.readline()
            line = line.decode("utf8") 
            if(self.callback):
                self.callback(line)


def getSubInfo(text):
    print("子进程测试代码实时输出内容=>" + text)

def main():

    cmd = [
            'python',
            '-u', # 注意,这里必须带上-u
            'testSub.py'
            ]
    print("子进程测试代码的运行命令:", ' '.join(cmd))
    testProcess = CMDProcess(cmd,getSubInfo )
    testProcess.start()

main()

3. 考虑缓存情况下的实现

此种情况适用于子进程消息较多且输出速度快,比如yolov5模型的训练,输出里面存在进度条显示,数据量较大且速度很快。

这里,只需要提供主进程代码即可,请注意相关注释内容。该代码为主进程代码testMain.py,用subprocess.popen运行子进程testSub.py,并获得子进程的实时打印结果。

python 复制代码
import subprocess
import threading

class CMDProcess(threading.Thread):
    '''
        执行CMD命令行的 进程
    '''
    def __init__(self, args,callback):
        threading.Thread.__init__(self)
        self.args = args
        self.callback=callback
        self.cwd = './' 
        
    def run(self):
        self.proc = subprocess.Popen(
            self.args,
            bufsize=1, # bufsize=0时,为不缓存;bufsize=1时,按行缓存;bufsize为其他正整数时,为按照近似该正整数的字节数缓存
            shell = False,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT, # 这里可以显示yolov5训练过程中出现的进度条等信息
            text=True, # 缓存内容为文本,避免后续编码显示问题
            cwd=self.cwd # 这个参数意思是,当前子进程结束后,其结果保存地址,比如yolov5训练进程结束后会输出模型、检测图片等,可在cwd中找到
        )
        
        while self.proc.poll() is None:
            line = self.proc.stdout.readline()
            self.proc.stdout.flush() # 刷新缓存,防止缓存过多造成卡死
            #line = line.decode("utf8") 
            if(self.callback):
                self.callback(line)


def getSubInfo(text):
    print("子进程测试代码实时输出内容=>" + text)

def main():

    cmd = [
            'python',
            '-u', # 注意,这里必须带上-u
            'testSub.py'
            ]  
    # 这里可以改成yolov5的训练代码,如下
    """
    cmd = [
            'python',
            '-u', # 注意,这里必须带上-u
            'train.py',
            '--img',
            '640',
            '--batch',
            '4',
            '--epochs',
            '1' #等等,请自行添加参数
            ] 
	"""
    print("子进程测试代码的运行命令:", ' '.join(cmd))
    testProcess = CMDProcess(cmd,getSubInfo )
    testProcess.start()

main()

搭配qt显示,效果如下

相关推荐
全栈练习生6 小时前
AI Agent 沙箱
python·ai
SEO_juper7 小时前
用 Python 写一个 GEO 可见性检查脚本:你的网站现在能被 AI 引用吗
开发语言·人工智能·爬虫·python·seo·外贸独立站
用户8356290780518 小时前
使用 Python 对 Excel 工作表进行排序
后端·python
for_ever_love__9 小时前
MySQL 全文索引实战:FULLTEXT、ngram 中文分词与 MATCH AGAINST 到底该怎么用
java·python·mysql·全文检索·分词·索引·ngram
用户8356290780519 小时前
使用 Python 合并 PowerPoint 演示文稿
后端·python
weixin_461769409 小时前
VS Code 中创建 Jupyter 文件(.ipynb)
ide·python·jupyter
2601_966949659 小时前
多市场量化策略的数据接口应该如何设计:从数据层架构到策略接入
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
全栈弄潮儿9 小时前
Python实战第1期:Python环境搭建与第一个程序
python
心易行者9 小时前
Agent应用+API端点商业化进阶实战:从单体智能体到可付费调用的API全流程
运维·服务器·人工智能·python·apache
weixin1997010801610 小时前
《1688图片空间API踩坑:img.upload 与 album.* 的防盗链与CDN缓存问题》(附Python源码)
开发语言·python·缓存