首页 > 编程问答 >如何使用 PIPE 并行运行 python 子进程?

如何使用 PIPE 并行运行 python 子进程?

时间:2024-07-30 15:36:53浏览次数:16  
标签:python subprocess

我正在使用 inkscape 将一堆 SVG 图像转换为 PNG。 单线程:


import subprocess
import time
import os

inkscape_path = r'C:\Program Files\Inkscape\bin\inkscape.com'

steps=30
filenames = []
processes = []

# t_start = time.process_time()
t_start = time.time()
for i in range(steps):
    template = bytes(f"""<?xml version="1.0" encoding="UTF-8"?>
    <svg width="100" height="100" viewBox="-10 -10 30 30" xmlns="http://www.w3.org/2000/svg">                   
    <line x1="0" y1="0" x2="{i*9/(steps-1)+1}" y2="0" stroke="green"/>
    </svg>
    """,'UTF-8')

    filename = f'img{i:02}.png'
    filenames.append(filename)

    process = subprocess.run([inkscape_path, '-p', '-o', filename],input=template )

# elapsed_time = time.process_time() - t_start
elapsed_time = time.time() - t_start

print(elapsed_time)

这可以工作,30 个图像总共需要 85 秒。

如果我用 communications() 尝试它,它会等待每个进程的完成。因此,我将超时设置为 0 并忽略引发的异常。


import subprocess
import time
import os

inkscape_path = r'C:\Program Files\Inkscape\bin\inkscape.com'

steps=30
filenames = []
processes = []

# t_start = time.process_time()
t_start = time.time()
for i in range(steps):
    template = bytes(f"""<?xml version="1.0" encoding="UTF-8"?>
    <svg width="100" height="100" viewBox="-10 -10 30 30" xmlns="http://www.w3.org/2000/svg">                   
    <line x1="0" y1="0" x2="{i*9/(steps-1)+1}" y2="0" stroke="green"/>
    </svg>
    """,'UTF-8')

    filename = f'img{i:02}.png'
    filenames.append(filename)

    process = subprocess.Popen([inkscape_path, '-p', '-o', filename],stdin= subprocess.PIPE, env=dict(os.environ, SELF_CALL="xxx") )

    try:
        process.communicate(template,timeout=0)
    except:
        pass
   
    processes.append(process)
    
for p in processes:
    p.wait()

# elapsed_time = time.process_time() - t_start
elapsed_time = time.time() - t_start

print(elapsed_time)

这有效并需要 30 秒,但我认为这不是一个干净的方法。

如何并行运行多个这些子进程以干净的方式。最好在 1 行中。

(SELF_CALL 是一种解决方法,因为 inkscape 有时会在多个实例运行时引发异常)


可以使用线程池来并行运行多个子进程,而无需等待每个子进程完成。以下是如何使用 concurrent.futures 库执行此操作的示例:

import subprocess
import time
import os
from concurrent.futures import ThreadPoolExecutor

inkscape_path = r'C:\Program Files\Inkscape\bin\inkscape.com'

steps = 30

def generate_svg(i):
    return bytes(f"""<?xml version="1.0" encoding="UTF-8"?>
    <svg width="100" height="100" viewBox="-10 -10 30 30" xmlns="http://www.w3.org/2000/svg">                   
    <line x1="0" y1="0" x2="{i*9/(steps-1)+1}" y2="0" stroke="green"/>
    </svg>
    """, 'UTF-8')

def convert_to_png(i):
    filename = f'img{i:02}.png'
    template = generate_svg(i)
    process = subprocess.run(
        [inkscape_path, '-p', '-o', filename],
        input=template,
        env=dict(os.environ, SELF_CALL="xxx")
    )

t_start = time.time()

# 使用线程池并行运行转换
with ThreadPoolExecutor() as executor:
    executor.map(convert_to_png, range(steps))

elapsed_time = time.time() - t_start

print(elapsed_time)

这个代码示例做了以下事情:

  1. 定义 generate_svg 函数: 此函数接受一个索引 i 并返回相应的 SVG 图像数据作为字节字符串。
  2. 定义 convert_to_png 函数: 此函数接受一个索引 i ,生成 SVG 数据,然后使用 subprocess.run 调用 Inkscape 将其转换为 PNG。
  3. 使用 ThreadPoolExecutor 创建一个线程池,并使用 executor.map 函数将 convert_to_png 函数并行应用于 range(steps) 中的每个索引。这将启动多个线程,每个线程负责将一个 SVG 图像转换为 PNG。
  4. 测量执行时间: 记录开始和结束时间,并打印总执行时间。

通过使用线程池,可以利用多核处理器来并行处理图像转换,从而显着减少总执行时间。

标签:python,subprocess
From: 78808552

相关文章

  • Python sqlite3 删除数据
    要从SQLite表中删除记录,你需要使用DELETEFROM语句。要删除特定的记录,你需要同时使用WHERE子句。要更新特定的记录,你需要同时使用WHERE子句。语法以下是SQLite中DELETE查询的语法- DELETEFROMtable_name[WHEREClause]PythonCopy例子假设我们使用以下查询创建了......
  • Python 环境配置(一)Python、Anaconda、Pycharm的安装
    Python环境配置(一)Python、Anaconda、Pycharm的安装本人之前已安装一次,此次为卸载之后的重新安装。。。一、Python1、下载下载官网:下载链接:DownloadPython|Python.org勾选添加到路径(环境变量)next如图所示之后点close关闭2、验证win+Rcmd:python退出ex......
  • Pycharm 设置 yaml 格式接口测试用例模板 (python+pytest+yaml)
    前言初次编写的伙伴们可能对yaml格式不太熟悉,自己写yaml用例的时候,总是格式对不齐啊记不住设定好的关键字啊等等等琐事是我们可以在pycharm上设置用例模块,通过快捷方式调用出对应的模块,达到高效写用例的目的。 pycharm操作集:1、File-Settings(快捷键Ctrl+Alt+S) 2、Live......
  • Python - Redirecting output of print to a file
    Theprintfunctioncanalsobeusedtowritetoafile.Theoutputofprint,thatisbydefault,senttothescreencanberedirectedtoanopenfile.Forthis,youhavetosupplythefileobjectasanargumentforthenamedparameterfile.Hereisanexa......
  • Python:添加到相对于当前运行脚本的 sys.path 的最佳方法
    我有一个充满脚本的目录(比如说project/bin)。我还有一个位于project/lib的库,并希望脚本自动加载它。这是我通常在每个脚本的顶部使用的:#!/usr/bin/pythonfromos.pathimportdirname,realpath,sep,pardirimportsyssys.path.append(dirname(realpath(_......
  • python身份证号码+姓名一致性核验、身份证号码真伪查询API集成
    身份证号码+姓名核验的方式,顾名思义是身份证二要素核验,一般情况下,身份证真伪查询需要上公安户籍系统查询,但此种方式仅适合个人查询,企业要想随时随地实现身份证实名认证的功能,便需要集成身份证实名认证接口功能。翔云人工智能开放平台提供身份证号实名认证接口,实时联网,上传身份证......
  • 如何将数字分配给返回的 python 数据列表,我可以调用这些数据来打印
    这里完全是菜鸟。我在网上搜索过,找不到我想要做的事情的答案。我的代码在这里:importbs4asbsimporturllib.requestsauce=urllib.request.urlopen('https://www.amazon.com/gp/rss/bestsellers/kitchen/289851/ref=zg_bs_289851_rsslink').read()soup=bs.Beautiful......
  • python API增值税发票四要素核验、数电票查验、医疗票查验
    长期以来,对发票进行高效的管理一直困扰着众多企业财务,手动录入效率慢、出错率高、纸质发票易丢失等。今天,翔云为广大企业提供了发票查验接口与财政票据查验接口服务,可针对增值税发票管理系统开具发票,医疗票据、非税收入等财政类票据进行真伪查验。翔云发票识别接口,使得企业财务无......
  • 如何使用 python 在 influxdb 中创建组织和存储桶
    如何使用python在influxdb中创建组织和存储桶?我有一个python脚本,用于在influxdb中创建组织和存储桶,但它无法工作并返回未经授权的响应任何人可以使用influxdbapi帮助我解决这个问题吗?HTTPresponsebody:{"code":"unauthorized","message":"write:org......
  • Python - File opening modes and buffering
    'r'-readmode(default)'w'-writemode'a'-appendmode'x'-exclusivecreationWeknowthatthemode'r'opensanexistingfileforreadingonly;thefileshouldalreadyexist.Ifyouopenafilein......