Thanks for the suggestion. Although it seems like it should work, it does not, it returns the wrong PID. I tried it. In the following example, the correct PID to kill is '3', but subprocess.Popen.pid (a.k.a. server.pid) returns '2'. Here is a shortened example:

import sys
import subprocess
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtWebKit import *

# Create a Qt application
app = QApplication(sys.argv)

pids = pm.get_python_pids()
print "PID list 1:"
print pids
## Assuming no other Python things are running,
## this prints a list of one PID, e.g. ['1']

# Start the Django server
server = subprocess.Popen(["python", manage_path, "runserver"])

pids_1 = pm.get_python_pids()
print "PID list 2:"
print pids_1
## Prints a list of two PIDs, e.g. ['1', '2']

# Enter Qt application main loop
app.exec_()

# If execution reaches this point, then the GUI window was closed

# To kill the Django server, we must first figure out what
# its Windows PID is

pids_2 = pm.get_python_pids()
print "PID list 3:"
print pids_2
## Prints a list of three PIDs, e.g. ['1', '2', '3']
## The proper process to kill is whichever one is new in pids_2. That is to
## say, we should kill the process which is listed in pids_2 but is not
## present in pids_1. In this example, it would be PID '3'.

## Another idea to find the PID to kill:
print "Server PID:"
print server.pid
## This doesn't work. In the current example, this prints '2'.
## '2' is not the correct PID to kill, the correct PID
## is '3' in this example.

# max_kill is the maximum number of processes named 'python.exe' to kill
max_kill = 1
for pid in pids_2:
    if pid in pids_1:
        continue
    else:
        subprocess.call(["taskkill", "/F", "/pid", pid])
        max_kill -= 1
    if max_kill == 0:
        break

# Now exit Python entirely
sys.exit()

Trying to kill the Django server in this way is equivalent to server.kill() or server.terminate() or server.send_signal(CTRL_C_EVENT). The problem with those three is the same: they send the signal to PID '2', which is simply not the PID of the Django server. It is the PID bound to the Popen instance, but that is not correct.

Zak F.

On 9/7/12 4:33 AM, João Vale wrote:
Hi,

I think you're overcomplicating things when looking up Django's PID, the object returned by Popen already provides you that:

http://docs.python.org/library/subprocess.html#subprocess.Popen.pid

Cheers,
João



On Thu, Sep 6, 2012 at 6:18 PM, Zak <[email protected] <mailto:[email protected]>> wrote:

    To see my full solution, look at the code below. Here it is
    described in
    English:

    Use the Windows command 'tasklist' to get a list of all running
    processes. Unfortunately, several processes are named simply
    'python.exe', and I could not find a way to figure out which one
    corresponded to manage.py. If you kill the wrong 'python.exe'
    process, a
    process may essentially kill itself. If the process kills itself
    before
    it kills manage.py, then manage.py will not be killed at all.

    To solve this problem, I ran 'tasklist' several times and kept
    track of
    when new processes appeared and which PID they had. It turns out that
    three 'python.exe' processes are created, and you need to kill the
    third
    one.

    I eventually kill the process using 'taskkill /F /pid %s' %
    (pid_to_kill).

    Here is the code, simplified and merged into a single file:

    import re
    import subprocess

    pyPat = re.compile("(?m)^python\.exe\s+(?P<pid>\d+)")
    # pyPat matches if "python.exe" occurs at the start of a new line
    (not in
    # the middle), followed by one or more spaces, followed by one or more
    # digits. The digits are stored in the 'pid' group of the match
    object.

    def get_python_pids():
         tasklist = subprocess.check_output(["tasklist"])
         pids = []
         for mtch in pyPat.finditer(tasklist):
             pids.append(mtch.group('pid'))
         return pids


    import sys
    import subprocess
    from PySide.QtCore import *
    from PySide.QtGui import *
    from PySide.QtWebKit import *


    # Create a Qt application
    app = QApplication(sys.argv)
    # Create a browser window and show it
    browser = QWebView(None)
    browser.load(QUrl("http://127.0.0.1:8000/";))
    browser.show()

    # pids = pm.get_python_pids()
    # print "PID list 1:"
    # print pids
    ## Assuming no other Python things are running,
    ## this prints a list of one PID, e.g. ['1']

    # Start the Django server
    manage_path = local_settings.root_dir + 'manage.py'
    server = subprocess.Popen(["python", manage_path, "runserver"])

    pids_1 = pm.get_python_pids()
    # print "PID list 2:"
    # print pids_1
    ## Prints a list of two PIDs, e.g. ['1', '2']

    # Enter Qt application main loop
    app.exec_()

    # If execution reaches this point, then the GUI window was closed

    # To kill the Django server, we must first figure out what
    # its Windows PID is

    pids_2 = pm.get_python_pids()
    # print "PID list 3:"
    # print pids_2
    ## Prints a list of three PIDs, e.g. ['1', '2', '3']
    ## The proper process to kill is whichever one is new in pids_2.
    That is to
    ## say, we should kill the process which is listed in pids_2 but
    is not
    ## present in pids_1. In this example, it would be PID '3'.

    # max_kill is the maximum number of processes named 'python.exe'
    to kill
    max_kill = 1
    for pid in pids_2:
         if pid in pids_1:
             continue
         else:
             subprocess.call(["taskkill", "/F", "/pid", pid])
             max_kill -= 1
         if max_kill == 0:
             break

    # Now exit Python entirely
    sys.exit()

    Zak F.
    _______________________________________________
    PySide mailing list
    [email protected] <mailto:[email protected]>
    http://lists.qt-project.org/mailman/listinfo/pyside



_______________________________________________
PySide mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/pyside

Reply via email to