无法使用process.kill()或process.terminate()或os.kill()或psutil杀死Python子进程 [英] Unable to kill Python subprocess using process.kill() or process.terminate() or os.kill() or using psutil

查看:243
本文介绍了无法使用process.kill()或process.terminate()或os.kill()或psutil杀死Python子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用python,我正在并行启动两个子进程.一个是HTTP服务器,另一个是另一个程序的执行(CustomSimpleHTTPServer.py,这是由selenium IDE插件生成的python脚本,用于打开Firefox,导航到网站并进行一些交互).另一方面,我想在第二个子进程完成执行后停止执行第一个子进程(HTTP服务器).

Using python, I am starting two subprocesses in parallel. One is an HTTP Server, while other is an execution of another program(CustomSimpleHTTPServer.py, which is a python script generated by selenium IDE plugin to open firefox, navigate to a website and do some interactions). On the other hand, I want to stop execution of the first subprocess(the HTTP Server) when the second subprocess is finished executing.

我的代码的逻辑是硒脚本将打开一个网站.该网站将自动对我的HTTP Server进行一些GET调用.在完成硒脚本后,应该关闭HTTP Server,以便它可以将所有捕获的请求记录在文件中.

The logic of my code is that the selenium script will open a website. The website will automatically make a few GET calls to my HTTP Server. After the selenium script is finished executing, the HTTP Server is supposed to be closed so that it can log all the captured requests in a file.

这是我的主要Python代码:

Here is my main Python code:

class Myclass(object):

HTTPSERVERPROCESS = ""

    def startHTTPServer(self):
        print "********HTTP Server started*********"
        try:
            self.HTTPSERVERPROCESS=subprocess.Popen('python CustomSimpleHTTPServer.py', \
                            shell=True, stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
        except Exception as e:
            print "Exception captured while starting HTTP Server process: %s\n" % e

    def startNavigatingFromBrowser(self):
        print "********Opening firefox to start navigation*********"
        try:
            process=subprocess.Popen('python navigationScript.py', \
                            shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            process.communicate()
            process.wait()
        except Exception as e:
            print "Exception captured starting Browser Navigation process : %s\n" % e
        try:
            if process.returncode==0:
                print "HTTPSERVEPROCESS value: %s" % self.HTTPSERVERPROCESS.returncode
                print self.HTTPSERVERPROCESS
                #self.HTTPSERVERPROCESS.kill()
                #self.HTTPSERVERPROCESS.terminate()
                #self.kill(self.HTTPSERVERPROCESS.pid)
        except Exception as e:
            print "Exception captured while killing HTTP Server process : %s\n" % e

    def kill(self,proc_pid):
        process = psutil.Process(proc_pid)
        for proc in process.get_children(recursive=True):
            proc.kill()
        process.kill()

    def startCapture(self):
        print "********Starting Parallel execution of Server initiation and firefox navigation script*********"
        t1 = threading.Thread(target=self.startHTTPServer())
        t2 = threading.Thread(target=self.startNavigatingFromBrowser())
        t1.start()
        t2.start()
        t2.join()

注意:执行通过调用startCapture()

这是CustomSimpleHTTPServer.py的代码,应该在终止时将捕获的请求写到logfile.txt:

Here is the code for CustomSimpleHTTPServer.py, which is supposed to write the captured requests to logfile.txt upon termination:

import SimpleHTTPServer
import SocketServer

PORT = 5555

class MyHTTPHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    log_file = open('logfile.txt', 'w')
    def log_message(self, format, *args):
        self.log_file.write("%s - - [%s] %s\n" %
                        (self.client_address[0],
                         self.log_date_time_string(),
                         format%args))

Handler = MyHTTPHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
httpd.serve_forever()

当我使用self.HTTPSERVERPROCESS.kill()或self.HTTPSERVERPROCESS.terminate()或os.kill()时,运行主Python代码后,我会在终端中关注

When I use self.HTTPSERVERPROCESS.kill() or self.HTTPSERVERPROCESS.terminate() or os.kill(), I get following in my terminal upon running the main Python code

********Starting Parallel execution of Server initiation and firefox navigation script*********
********SimpleHTTPServer started*********
********Opening firefox to start navigation*********
HTTPSERVEPROCESS value: <subprocess.Popen object at 0x1080f8410>
2459
Exception captured while killing HTTP Server process : [Errno 3] No such process


Process finished with exit code 0

当我使用self.kill(self.HTTPSERVERPROCESS.pid)时,运行主Python代码后,我会在终端中关注

And when I use self.kill(self.HTTPSERVERPROCESS.pid), I get following in my terminal upon running the main Python code

********Starting Parallel execution of Server initiation and firefox navigation script*********
********SimpleHTTPServer started*********
********Opening firefox to start navigation*********
HTTPSERVEPROCESS value: <subprocess.Popen object at 0x1080f8410>
2459
Exception captured while killing HTTP Server process : 'Process' object has no attribute 'get_children'


Process finished with exit code 0

以下三个都不能够杀死HTTPServer进程:

Neither of the following 3 are able to kill the HTTPServer process:

self.HTTPSERVERPROCESS.kill()
self.HTTPSERVERPROCESS.terminate()
self.kill(self.HTTPSERVERPROCESS.pid)

我知道CustomSimpleHTTPServer.py是正确的,因为当我分别运行它并手动浏览到网站,然后通过在终端中按CTRL-c手动终止CustomSimpleHTTPServer.py脚本时,日志将填充在logfle.txt中.

I know that CustomSimpleHTTPServer.py is correct because when I run it seperately and manually browse to the website, and then manually terminate the CustomSimpleHTTPServer.py script by hitting CTRL-c in terminal, the logs are populated in logfle.txt.

我应该对代码进行哪些更改,以使其正常运行并填充日志?

What changes do I make to my code so that it works properly and logs are populated?

推荐答案

您应该只使用os.kill()来指示进程:

You should just use os.kill() to signal processes:

import os
import signal
...
os.kill(the_pid, signal.SIGTERM)   # usually kills processes
os.kill(the_pid, signal.SIGKILL)   # should always kill a process

此外,如果您杀死父进程,它通常也会杀死子进程.

Also, if you kill the parent process it also usually kills the children.

更新:

我对Server程序做了两个小改动:

I made two small changes to the Server program:

  • self.log_file.flush()添加呼叫以确保日志条目 被刷新到日志文件.
  • 覆盖allow_reuse_address,以便您可以重复使用 终止服务器后不久使用相同的地址. (请参见此SO问题)
  • Add a call to self.log_file.flush() to make sure log entries are flushed out to the log file.
  • Override allow_reuse_address so that you can reuse the same address shortly after terminating the server. (See this SO question)

文件Server:

#!/usr/bin/env python

import SimpleHTTPServer
import SocketServer
PORT = 5555

class MyServer(SocketServer.TCPServer):
    allow_reuse_address = True

class MyHTTPHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    log_file = open('logfile.txt', 'w')
    def log_message(self, format, *args):
        self.log_file.write("%s - - [%s] %s\n" %
                        (self.client_address[0],
                         self.log_date_time_string(),
                         format%args))
        self.log_file.flush()

Handler = MyHTTPHandler
httpd = MyServer(("", PORT), Handler)
httpd.serve_forever()

这是一个简单的导航程序(文件Navigate):

Here is an simple navigation program (file Navigate):

#!/usr/bin/env python

import requests
import time

URL = "http://localhost:5555/"

def main():
  for x in range(5):
    print "x =", x
    r = requests.get(URL + "asd")
    time.sleep(1)
  print "Quitting"

main()

这是主程序:

#!/usr/bin/env python

import os
import subprocess
import signal

def main():
  # start web server
  web = subprocess.Popen(["./Server"])
  print "web server pid:", web.pid

  # start navigator
  nav = subprocess.Popen(["./Navigate"])
  print "nav pid: ", nav.pid

  # wait for nav to exit
  nav.wait()
  print "done waiting for nav"
  print "killing web server"
  os.kill(web.pid, signal.SIGTERM )
  web.wait()
  print "server terminated"

main()

这篇关于无法使用process.kill()或process.terminate()或os.kill()或psutil杀死Python子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆