前言

subprocess这个函数很好用,类似于控制台执行,功能很多,今天先介绍subprocess调用exe,并行调用两个或两个以上的exe。

Subprocess调用exe

调用exe有几种方式,这里介绍一下subprocess。

p = subprocess.Popen(“./XXX.exe param1 param2”, stdin=subprocess.PIPE, stdout=subprocess.PIPE)

返回值为p.returncode,exe中打印出来的消息为output= p.communicate()[0]

那么有的程序运行时特别耗资源,容易卡死,所以设置一个超时时间,如果在规定时间内可以分析完毕,返回分析结果,如果超时了,杀死exe,返回默认结果。

def Func():
p = subprocess.Popen("./XXX.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
try:
p.wait(timeout=SECONDS_TIMEOUT)
except Exception as e:
print("===== process timeout ======")
p.kill()
return None
    output= p.communicate()[0]
   err = p.communicate()[1]
   print(output)
   print(p.returncode)

Subprocess并行调用两个或两个以上的exe

方法一:多线程

知识点:多线程,路径分离,锁定程序运行路径

以并行调用三个exe为例。

1. readini.exe

功能:读取同级目录testini.ini里面的一个值,等待3秒,写入同级目录test1.ini里面

testini.ini

[TEST]
name = Sindy
age = 20
sex = girl
score = 90

2. rose.exe

功能:画一朵玫瑰花,大概运行8S。

3. Usage.exe

功能:画一个动态折线图,时间20S。

CallEXEParaller.py

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
"""=================================================
@Project -> File : 20200613 -> CallEXEParaller.py
@IDE : PyCharm
@Author : zihan
@Date : 2020/6/13 14:20
@Desc :目的:可以并行调用两个或者多个EXE
================================================="""
import subprocess
import sys
import os
import threading SECONDS_TIMEOUT = 1000 def execute_exe(exe_path, exe_param):
folder_path, file_name = os.path.split(exe_path)
# os.chdir(folder_path)
p = subprocess.Popen(exe_path + " " + exe_param, stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=folder_path)
try:
p.wait(timeout=SECONDS_TIMEOUT)
except Exception as e:
p.kill()
# os.chdir(current_path)
print("===== process timeout ======")
return None
except:
s = sys.exc_info()
str_error = "Error '%s' happened on line %d" % (s[1], s[2].tb_lineno)
p.kill()
# os.chdir(current_path)
return None
# os.chdir(current_path)
output = p.communicate()[0]
err = p.communicate()[1]
print(output)
print(p.returncode) if __name__ == '__main__':
current_path = os.getcwd()
readini_abs_path = current_path + "\\" + r"EXEModule\ReadINI\readini.exe"
rose_abs_path = current_path + "\\" + r"EXEModule\Rose\rose.exe"
usage_abs_path = current_path + "\\" + r"EXEModule\CPUUsage\CPUUsage.exe"
t1 = threading.Thread(target=execute_exe, args=(readini_abs_path, ""))
t2 = threading.Thread(target=execute_exe, args=(rose_abs_path, ""))
t3 = threading.Thread(target=execute_exe, args=(usage_abs_path, ""))
t1.start()
t2.start()
t3.start()

注意subprocess的cwd参数,它可以指定当前exe运行在哪个路径下。程序中执行的就是如果调用哪个exe,那么就在exe所在的目录下执行程序。

方法二:多进程

在用多线程运行时发现了一个问题,如果在exe运行完后要作出相应的操作,那么必须得耗时最长的程序运行完后,在一起打印消息。这是因为p.communicate()[0]在阻塞的原因。解决此问题的方法就是用多线程进行调用。

CallEXEParallel.py

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
"""=================================================
@Project -> File : 20200613 -> CallEXEParaller.py
@IDE : PyCharm
@Author : zihan
@Date : 2020/6/13 14:20
@Desc :目的:可以并行调用两个或者多个EXE
方法一:多进程方法调用,完美实现
方法二:多线程调用,因为有p.communicate()[0]的存在,会导致打印阻塞,一直等到耗时长的程序执行完才会打印消息
================================================="""
import subprocess
import sys
import os
import threading
import multiprocessing def execute_exe(exe_path, exe_param):
print("aaa")
folder_path, file_name = os.path.split(exe_path)
try:
p = subprocess.Popen(exe_path + " " + exe_param, stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=folder_path)
except:
s = sys.exc_info()
str_error = "Error '%s' happened on line %d" % (s[1], s[2].tb_lineno)
print(str_error)
return None
output = p.communicate()[0]
err = p.communicate()[1]
print(output)
print(p.returncode)
if p.returncode == 0:
print("pass")
else:
print("fail") # 方法一:多进程方法调用
def multiprocess_test():
current_path = os.getcwd()
readini_abs_path = current_path + "\\" + r"EXEModule\ReadINI\readini.exe"
rose_abs_path = current_path + "\\" + r"EXEModule\Rose\rose.exe"
usage_abs_path = current_path + "\\" + r"EXEModule\CPUUsage\CPUUsage.exe" p1 = multiprocessing.Process(target=execute_exe, args=(readini_abs_path, ""))
p1.start()
p2 = multiprocessing.Process(target=execute_exe, args=(rose_abs_path, ""))
p2.start()
p3 = multiprocessing.Process(target=execute_exe, args=(usage_abs_path, ""))
p3.start() p1.join()
p2.join()
p3.join() # 方法二:多线程方法调用
def threading_test():
current_path = os.getcwd()
readini_abs_path = current_path + "\\" + r"EXEModule\ReadINI\readini.exe"
rose_abs_path = current_path + "\\" + r"EXEModule\Rose\rose.exe"
usage_abs_path = current_path + "\\" + r"EXEModule\CPUUsage\CPUUsage.exe" t1 = threading.Thread(target=execute_exe, args=(readini_abs_path, ""))
t2 = threading.Thread(target=execute_exe, args=(rose_abs_path, ""))
t3 = threading.Thread(target=execute_exe, args=(usage_abs_path, "")) t1.start()
t2.start()
t3.start() t1.join()
t2.join()
t3.join() if __name__ == '__main__':
# threading_test()
multiprocess_test()

OK.

Python基础之subprocess的更多相关文章

  1. python基础教程

    转自:http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html Python快速教程 作者:Vamei 出处:http://www.cn ...

  2. Python 基础之socket编程(二)

    Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 ...

  3. Python基础-week05

    本节大纲:Author:http://www.cnblogs.com/Jame-mei 模块介绍 time & datetime模块 random os sys shutil json &am ...

  4. python基础之socket编程 (转自林海峰老师)

    python基础之socket编程   阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 ...

  5. python基础系列教程——Python3.x标准模块库目录

    python基础系列教程——Python3.x标准模块库目录 文本 string:通用字符串操作 re:正则表达式操作 difflib:差异计算工具 textwrap:文本填充 unicodedata ...

  6. python基础 — 致初学者的天梯

    Python简介 Python是一种计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新 功能的添加,越来越多被用于独立的.大型项目 ...

  7. python基础31[常用模块介绍]

    python基础31[常用模块介绍]   python除了关键字(keywords)和内置的类型和函数(builtins),更多的功能是通过libraries(即modules)来提供的. 常用的li ...

  8. (Python基础教程之二十二)爬虫下载网页视频(video blob)

    Python基础教程 在SublimeEditor中配置Python环境 Python代码中添加注释 Python中的变量的使用 Python中的数据类型 Python中的关键字 Python字符串操 ...

  9. python之最强王者(2)——python基础语法

    背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...

随机推荐

  1. 二、部署监控服务器-Zabbix Server

    二.部署监控服务器-Zabbix Server 1)源码安装Zabbix Server 多数源码包都是需要依赖包的,zabbix也- 样,源码编译前需要先安装相关依赖包. [root@zabbixse ...

  2. 解决git冲突

    多个开发者同时操作git中的同一个文件,第一个人在commit和push的时候是可以正常提交的,而之后的开发者执行pull,就会报冲突异常conflict. 解决方案: 全部采用当前更改 之后再去gi ...

  3. 还在担心写的一手烂SQL,送你4款工具

    对于正在运行的mysql,性能如何,参数设置的是否合理,账号设置的是否存在安全隐患,你是否了然于胸呢? 俗话说工欲善其事,必先利其器,定期对你的MYSQL数据库进行一个体检,是保证数据库安全运行的重要 ...

  4. 树莓派FRP内网穿透及自启动

    内网穿透的步骤和文件存档 实验室在远方部署了电脑主机来采集数据和图片,每次去调试会很麻烦,因而使用FRP内网穿透使得我们可以在实验室访问主机. 主要功能 实现远程可访问和开机自启FRP程序服务 安装和 ...

  5. JAVA实现按列表中元素的时间字段排序

    JAVA代码实现按列表中元素的时间字段排序 导语: 工作中遇到一个问题,调用第三方接口返回的数据没有按时间倒序排列,测试说要加,然后在网上找到一个解决办法,这里记录一下 需求: 如下图列表,按生日进行 ...

  6. [HTML]常用的文本标签(标题、段落、加粗、下划线等标签)

    标签类型 写法 说明 标题 <h1></h1>......<h6></h6> 加粗.独占一行(块级元素) 段落 <p></p> ...

  7. 4、基本数据类型(init、bool)

    4.1.数字: 1.age = 21 weight = 64 fight = 5 2.数字的特点: (1)数字是不可变数据类型(不可以增加,删除,修改元素) (2)数字可以直接访问 (3)数字不可使用 ...

  8. ES6深度解析3:Generators

    介绍ES6 Generators 什么是Generators(生成器函数)?让我们先来看看一个例子. function* quips(name) { yield "hello " ...

  9. Elasticsearch的配置学习笔记

    文/朱季谦 Elasticsearch是一个基于Lucene的搜索服务器.它提供一个分布式多用户能力的全文搜索引擎,基于RESTful web接口,Elasticsearch是用Java语言开发的. ...

  10. Redis主从,集群部署及迁移

    工作中有时会遇到需要把原Redis集群下线,迁移到另一个新的Redis集群的需求(如机房迁移,Redis上云等原因).此时原Redis中的数据需要如何操作才可顺利迁移到一个新的Redis集群呢? 本节 ...