简体   繁体   English

Python使用subprocess.Popen关闭所有线程或进程

[英]Python close all threads or processes with subprocess.Popen

I work on a simple gui application. 我在一个简单的GUI应用程序上工作。

In my real case, this application starts Django ( python manage.py runserver ) webserver and close Django webserver. 在我的实际情况下,此应用程序启动Django( python manage.py runserver )网络服务器,然后关闭Django网络服务器。 In order to, simplify the testability of my app, I replace django start webserver by sleep command. 为了简化我的应用程序的可测试性,我用sleep命令替换了django start webserver。

When I fire Start server button : the server starts. 当我启动服务器按钮时:服务器启动。 Then, I fire Stop server button, and the process closes. 然后,我触发“ 停止服务器”按钮,该过程关闭。

But the django webserver (or sleep command) is still working. 但是django网络服务器(或sleep命令)仍在工作。

How can I stop the process AND stop de command called by subprocess.Popen ? 如何停止进程并停止由subprocess.Popen调用的命令?

There is my code : 有我的代码:

#!/usr/bin/python
# coding:utf-8
import os
import sys
import subprocess
import time
import datetime
import zipfile
import subprocess
from concurrent import futures
from threading import Thread
from multiprocessing import Process

try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

def runserver():
    cmd = 'sleep 60'
    # os.system(cmd)
    subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
    print('TERMINATE BY TIMEOUT')
    return True

class WindowMain:

    def __init__(self, master):
        self.thread_srv = None
        self.master = master
        self.frame = tk.Frame(self.master)

        self.lbl = tk.Label(text="")
        self.lbl.pack()

        self.btn_quit = tk.Button(self.frame, text="Stop server", width=25, command=lambda:  self.stop_server())
        self.btn_quit.pack()

        self.button1 = tk.Button(self.frame, text="Start Server", width=25, command=lambda: self.runserver_thread())
        self.button1.pack()

        self.frame.pack()

    def stop_server(self):
        if self.thread_srv:
            print('THREAD')
            self.thread_srv.terminate()
        else:
            print("NOT THREAD")

    def runserver_thread(self):
        self.thread_srv = Process(target=runserver)
        self.thread_srv.start()

current_dir = os.path.dirname(os.path.abspath(__file__))

def quit(root):
    root.quit
    sys.exit()

def main():
    root = tk.Tk()
    tk.Button(root, text="Quitter", command=lambda: quit(root)).pack()
    app = WindowMain(root)
    root.mainloop()

if __name__ == '__main__':
    main()

Solution (after ForceBru's answer) 解决方法(在ForceBru回答之后)

I code this function which close django server : 我编码此功能关闭Django服务器:

def close_django_runserver():
    if 'win' in sys.platform:
        pass
    else:
        cmd = 'ps aux'
        output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
        process_list = output.split("\n")
        for process in process_list:
            if 'manage.py' in process and 'runserver' in process:
                pid = re.sub(r'^[^\s]+\s+(\d+)\s+.*$', r'\1', process)
                subprocess.Popen('kill '+str(pid), shell=True, stdout=subprocess.PIPE).stdout.read()

It certainly exists a better solution, bu it works. 当然,它可以存在更好的解决方案。 I will code Windows solution at a later time. 我将在以后编写Windows解决方案的代码。

You run the Django start script, everything gets initialized and set up and then that newly created Django process goes to background (gets * daemonized*) disconnected from your thread . 您运行Django启动脚本,所有东西都初始化并设置好,然后新创建的Django进程进入后台( 与线程断开连接 )(获取*守护进程*)。

So, when you kill that thread, you actually kill nothing because that start-up script has done its job and has probably already exited. 因此,当您杀死该线程时,实际上并没有杀死任何东西,因为该启动脚本已经完成了工作,并且可能已经退出了。

After the start-up script is run, a new Django process is created . 运行启动脚本后,将创建一个新的Django进程 Experiment on your machine and find its name. 在您的计算机上进行实验并找到其名称。 Then you can run something like sudo killall django_process from within your program. 然后,您可以在程序中运行sudo killall django_process之类的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM