前言

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. hbase统计表的行数的三种方法

    有些时候需要我们去统计某一个hbase表的行数,由于hbase本身不支持SQL语言,只能通过其他方式实现. 可以通过一下几种方式实现hbase表的行数统计工作: 这里有一张hbase表test:tes ...

  2. Go语言实现的23种设计模式之结构型模式

    摘要:本文主要聚焦在结构型模式(Structural Pattern)上,其主要思想是将多个对象组装成较大的结构,并同时保持结构的灵活和高效,从程序的结构上解决模块之间的耦合问题. 本文分享自华为云社 ...

  3. 在C++中,你真的会用new吗?

    摘要:"new"是C++的一个关键字,同时也是操作符.关于new的话题非常多,因为它确实比较复杂,也非常神秘. 本文分享自华为云社区<如何编写高效.优雅.可信代码系列(2)- ...

  4. 低代码开发LCDP,Power Apps系列 - 搭建入职选购电脑设备案例

    低代码简介 上世纪八十年代,美国就有一些公司和实验室开始了可视化编程的研究,做出了4GL"第四代编程语言",到后来衍生成VPL"Visual Programming La ...

  5. upload-labs通关记录

    upload-labs通关记录 一句话木马解读 一般的解题步骤 或者可以直接用字典爆破一下 https://github.com/TheKingOfDuck/fuzzDicts/blob/master ...

  6. Nginx网站服务

    1.常见的网站服务 静态网站服务: Apache服务 nginx服务 动态网站服务: Tomcat服务 PHP 2.nginx网站服务特点 (1)nginx具有高并发(特别是静态资源).占用系统资源少 ...

  7. jenkins pipeline构建后发送邮件通知

    jenkins pipeline构建后发送邮件通知 mail配置 进入系统配置 找到最下边的邮件通知 创建任务 Pipeline片段 post { always { bat "" ...

  8. 导入项目发现没得右边没得maven

    使用ctrl + shift+A点Add Maven Project 就行了 参考:https://www.cnblogs.com/Juff-code/p/13390356.html

  9. DRF之权限和频率限制

    一.权限 权限可以限制用户对视图的访问和对具体数据对象的访问. 在执行视图的dispatch方法前,会先进行视图访问权限的判断 在通过get_object获取对象时,会进行模型对象访问权限的判断 源码 ...

  10. C++智能指针之shared_ptr与右值引用(详细)

    1. 介绍 在 C++ 中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露.解决这个问题最有效的方法是使用智能指针(smart pointer).智能指针是存储指向动态分配(堆)对象指针 ...