最近项目中遇到一个问题,就是在代码中使用subprocess.Popen()启动了一个python进程,具体说是一个服务,比如:

p = subprocess.Popen('cd static && python -m SimpleHTTPServer {}'.format(port),
                      shell=True,
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE

原本想法是等主进程结束后就要终止的,因为这个服务只允许存在于主进程生命周期。但是实际情况是,主进程结束后,这个子进程并没有释放,事实上,上述代码干了2个事

1.开启一个python子进程,因为是python命令

2.打开一个dos终端进程,因为shell=True

而此时如果我们什么都不做,貌似这2个子进程都会残留,不会主动退出(具体没研究)。一般遇到这种情况,我首先想到kill pid,于是有了下面的逻辑:

os.system('taskkill /f /pid {}'.format(p.pid))

当我以为这样就大功告成的时候,事实教会我too young too simple!

因为这样只会杀掉DOS子进程,也就是shell开启的进程,但是python的子进程还在,然后又试了os.kill()、win32api、ctypes等办法,全都不行!

最后找到如下方法,搞定!

os.system('taskkill /t /f /pid {}'.format(p.pid))

TASKKILL [/S system [/U username [/P [password]]
         { [/FI filter] [/PID processid | /IM imagename] } [/F] [/T]

描述:
    这个命令行工具可用来结束至少一个进程。
    可以根据进程 id 或图像名来结束进程。

参数列表:

    S system 指定要连接到的远程系统。
    /U [domain\]user 指定应该在哪个用户上下文执行这个命令。
    /P [password] 为提供的用户上下文指定密码。如果忽略,提示输入。
    /F 指定要强行终止进程。
    /FI filter 指定筛选进或筛选出查询的的任务。
    /PID process id 指定要终止的进程的PID。
    /IM image name 指定要终止的进程的图像名。通配符 '*'可用来指定所有图像名。
    /T Tree kill: 终止指定的进程和任何由此启动的子进程。
    /? 显示帮助/用法。

    其实这个问题本身不难,但是初遇时基本能难倒一堆人,本质上这个不是代码逻辑的问题,二是对操作系统不够了解深入。这里涉及到不同的操作系统如何释放进程的问题,而恰恰不同的操作系统处理方式不同,比如现在百度搜“subprocess.Popen()终结子进程”问题,绝大多数都是Linux的做法,即:

os.killpg(int(p.pid),signal.SIGKILL)

但这个压根不适用于Windows平台,因为Windows就没有os.killpg方法。而os.kill本身也不起作用。

以上结论希望帮到其他同学,懒是不能懒的,继续学习吧!

1.背景 最近项目中遇到一个问题,就是在代码中使用subprocess.Popen()启动了一个python进程,具体说是一个服务,比如:p = subprocess.Popen('cd static && python -m SimpleHTTPServer {}'.format(port),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)原本想法是等主进程结束后就要终止的,因为这个服务只允许存在于主进...
自从工作了就好久没发博客,还是出来冒个泡=。=  前段时间写的一个项目需要用pythonsubprocess.Popen大量调用某shell命令,运行到一定量级之后就会产生内存溢出,造成大量线程阻塞,然后就会造成([Errno 24] Too many open files)这个异常。  网上有人说是close_fds=True这个参数在python2.x默认没打开,这个参数可以关闭文件描述
subprocess.Popensubprocess.Popen类用于在一个新进程中执行一个子程序。 本人在某个项目中,利用这个函数运行一些深度学习算法,但是在运行一些比较大的模型时会出现电脑卡死的情况,崩溃了好几次,发现是内存被占满了,当时没有想到是因为这个函数,后来在看 subprocess.Popen的文档时发现,利用subprocess.Popen运行的函数,读到的数据会被写在内存中,而且是没有限制的,会直接倒是系统崩溃。 但是如果使用os.system就会阻塞这个接口,我需要等到这个函数运行完
在之前的文章中,实现了Electron-vue在不同系统打包成安装程序。但这只是前端build/package之后的文件打包,虽然服务端的编译之后的exe文件也可以放到一起打包,并且可以去启动服务端程序。然而不能与服务端通信的话,那么这个程序存在的意义就不大。所以在这片文章中会讲一下怎么在安装之后,启动应用程序调用服务端程序,同时获取服务端的输出值/返回值。 由于不是传统意义上的前后端通信(常见的前后端通信,只需要使用http/https进行通信即可,request发送请求,response返回请
你可以使用此句柄终止使用ctypes或pywin32扩展名的子进程。 # Create a process that won't end on its own import subprocess process = subprocess.Popen(['python.exe', '-c', 'while 1: pass']) # Kill the process using pywin32
from subprocess import Popen,PIPE 1.光标处于闪烁等待状态,不能实时输出测试cmd界面. [原因]:使用communicate()函数,需要等脚本执行完才返回。 def communicate(self, input=None): """Interact with process: Send data to stdin. Read data fr...
logcmd = "adb logcat -v time > C:\log.txt" self.Popen = subprocess.Popen(logcmd ,stdout = subprocess.PIPE,shell=True) 用上面的方法来获取logcat的信息,它的实际原理是另外开启一个cmd命令来运行adb logcat的命令,即使后面用popen.te
subprocessPython 2.4中新增的一个模块,它允许你生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码; 本文主要举例说明其中Popen的使用: subprocess.Popen(): 在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等。这个...
Qt—使用Qt实现多线程设计的四种方法 一、写在前面 ​ 这篇文章内容是:关于Qt多线程应用设计,在Qt中提供了四种方法来进行多线程编程和设计。合理的选择对应的方法来解决实际开发中遇到的开发问题有助于对应用程序进行更合理设计。 文章目录Qt—使用Qt实现多线程设计的四种方法一、写在前面二、【方法一】 QThread:带有可选事件循环的底层API三、【方法二】 QThreadPool和QRunnable:重用线程四、【方法三 】Qt并发:使用高级API五、【方法四】 WorkerScript:QML中的线程化
# Create a process that won't end on its own import subprocess process = subprocess.Popen(['python.exe', '-c', 'while 1: pass']) # Kill the process using pywin32 import win32api win32api.TerminatePr
文章目录一、用 PyCharm 进行远程调试debugger1. 方法1:我们配置了远程解释器1.1 pycharm可以远程解释器运行,但是不能debug2. 方法2 使用 Python 远程调试服务器配置2.2 远程调试原理 一、用 PyCharm 进行远程调试debugger 官网:Remote Debugging with PyCharm 用 PyCharm 进行远程调试 https://www.jetbrains.com/help/pycharm/remote-debugging-with-pr
Django启动报错:UnicodeDecodeError: 'utf8' codec can't decode byte 0xc1 in position 0: invalid start byte m0_68916795: 确实挺不错的 selenium Xpath应用疑难一:contains的用法 qiuqiu202111: Django启动报错:UnicodeDecodeError: 'utf8' codec can't decode byte 0xc1 in position 0: invalid start byte qq_57137967: 改成英语就可以了!爱了爱了 Jmeter之ERROR o.a.j.c.CSVDataSet: java.io.IOException: Cannot have quote-char in plain field:[{"] 泠月飞花: 上面不是说解决办法了么 Jmeter之ERROR o.a.j.c.CSVDataSet: java.io.IOException: Cannot have quote-char in plain field:[{"] xpp2812: 楼主找到好的解决办法了吗?请赐教。。。。