2016-03-14 117 views
1

我工作在一个简单的GUI应用程序。Python关闭所有线程或进程与子进程.Popen

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

当我着火启动服务器按钮:服务器启动。 然后,我启动停止服务器按钮,并且进程关闭。

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

如何停止进程并停止由调用的子命令subprocess.Popen

有我的代码:

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

它肯定存在一个更好的解决方案,BU有用。我将在稍后编写Windows解决方案。

回答

2

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

因此,当你杀死那个线程时,你实际上并没有杀死任何东西,因为这个启动脚本已经完成了它的工作并且可能已经退出了。

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

+0

感谢您的回答,但有没有办法从我的脚本中关闭django服务器? – jedema

+0

@jedema,我想是的,请看我编辑的答案 – ForceBru

+0

谢谢,我会试试这个。 – jedema