前言

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.

最新文章

  1. Can't load AMD 64-bit .dll on a IA 32-bit platform
  2. 怎么找到占用usb的模块,linux下Jlink连接失败
  3. Java中将unix时间戳转化为正常显示时间
  4. windows程序防狼术入门
  5. Altium Designer 6三维元件库建模教程
  6. unresolved import 解决办法
  7. SQL学习之使用视图
  8. 无尽的循环ViewPager
  9. 以太网PHY 芯片之 MII/MDIO接口详解
  10. 在JBoss AS7中进行项目部署
  11. RTX腾讯通字体全变成横着的了
  12. mysql com.mysql.cj.jdbc.Driver 配置
  13. ASP.NET MVC显示UserControl控件(扩展篇)
  14. Redis 密码设置和查看密码
  15. 《Mysql技术内幕,Innodb存储引擎》——索引与算法
  16. SVN For Mac: Cornerstone.app破解版免费下载
  17. JAVA-JSP动作元素之param
  18. Java中 方法的多态 简析图
  19. Java Integer为代表的包装类
  20. Go reflect反射

热门文章

  1. 源码学习之noop
  2. Unity3D学习笔记1——绘制一个三角形
  3. 20204107 孙嘉临 《PYTHON程序设计》实验四报告
  4. Terraform状态State管理,让变更有记录
  5. 什么是OSI的第7层
  6. Jenkins自动化CI&CD流水线
  7. 40、如何获取yum安装时的rpm包
  8. hud 3308 LCIS 线段树 区间合并
  9. redis为什么那么快?
  10. 【转载】Nginx多服务绑定80端口及映射域名