【问题标题】:Python close all threads or processes with subprocess.PopenPython 使用 subprocess.Popen 关闭所有线程或进程
【发布时间】:2016-03-14 13:30:49
【问题描述】:

我正在开发一个简单的 gui 应用程序。

在我的真实案例中,此应用程序启动 Django (python manage.py runserver) 网络服务器并关闭 Django 网络服务器。为了简化我的应用程序的可测试性,我将 django start webserver 替换为 sleep 命令。

当我触发 启动服务器 按钮时:服务器启动。 然后,我触发 Stop server 按钮,进程关闭。

但 django 网络服务器(或 sleep 命令)仍在工作。

如何停止由 subprocess.Popen 调用的进程 AND stop de 命令?

这是我的代码:

#!/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()

解决方案(在 ForceBru 的回答之后)

我编写了这个关闭 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()

它当然存在更好的解决方案,但它确实有效。稍后我将编写 Windows 解决方案。

【问题讨论】:

    标签: python django multithreading


    【解决方案1】:

    您运行 Django 启动脚本,一切都被初始化和设置,然后新创建的 Django 进程进入后台(得到 * daemonized*)与您的线程断开连接。

    所以,当你杀死那个线程时,你实际上什么也没有杀死,因为那个启动脚本已经完成了它的工作并且可能已经退出了。

    启动脚本运行后,一个新的 Django 进程被创建。在您的机器上进行实验并找到它的名称。然后你可以在你的程序中运行类似sudo killall django_process 的东西。

    【讨论】:

    • 感谢您的回答,但是有没有办法从我的脚本中关闭 django 服务器?
    • 谢谢,我试试这个。
    猜你喜欢
    • 2014-05-25
    • 2017-07-27
    • 2010-11-02
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    相关资源
    最近更新 更多