3

I'm using the distribution of Python2.5.2 included in the OSGeo4W installer. This is a 32-bit distribution running on Windows 7. Although PyQt is not installed by default by the OSGeo4W installer, we have installed it to the OSGeo4W Python installation and it has worked perfectly until now. PyQt4 is version 4.8.6, and was built against a 32-bit version of Python.

As part of a PyQt4-based UI, I currently spawn a QtCore.QProcess() and start it like this:

self.modelProcess = QtCore.QProcess()
command = './OSGeo4W/gdal_python_exec.bat'
argslist = 'QtCore.QString(uri, json.dumps(inputDict))
self.modelProcess.start(command, argslist)

where inputDict is a Python dictionary mapping python strings to arbitrary values and uri is a string URI to the desired script to be run.

While this process is running, the User is presented with a window containing several Qt widgets, including a 'cancel' button. I have the following signal/slot configuration for the 'cancel' button:

self.cancelButton = QtGui.QPushButton('Cancel')
self.cancelButton.clicked.connect(self.closeWindow)

And then elsewhere:

def closeWindow(self):
    self.modelProcess.kill()

According to the Qt documentation, this should kill the process (the PyQt documentation agrees on this point). Unfortunately, this does not kill the QProcess. If I have Windows Task Manager, I can see my CPU usage continue to escalate as the QProcess happily processes my program.

I have read elsewhere on SO that a subprocess can be killed in Python 2.5 by using os.kill(), but my distribution of Python does not include the kill function:

>>> import os
>>> os.kill
Traceback (most recent call last):
  File "(stdin)", line 1, in (module)
AttributeError: 'module' object has no attribute 'kill'

Is there a different approach to killing a process in Python? Some third-party module, perhaps?

Many thanks.

Community
  • 1
  • 1
James
  • 1,485
  • 2
  • 16
  • 21
  • [os.kill()](http://docs.python.org/library/os.html#os.kill) is a function requiring two arguments, not a parameter of [os](http://docs.python.org/library/os.html#module-os). Thus you need to call it with something like `os.kill(pid, signal)`. – GreenMatt Nov 22 '11 at 19:29
  • Oops! Lost track of you running on Windows, for which it seems you need at least Python 2.7. – GreenMatt Nov 22 '11 at 19:32
  • You might try: http://blogs.oracle.com/rajkumar/entry/how_to_kill_a_process or one of the other methods mentioned in the comments. I can't vouch for any of these as I don't have access to Windows right now. – GreenMatt Nov 22 '11 at 19:35
  • Hey GreenMatt, my program actually calls `os.kill` like this: ` os.kill(self.modelProcess.pid(), signal.SIGKILL)`. I'll check into pre-python2.7 approaches. – James Nov 22 '11 at 19:37
  • My first comment was in response to the `import os` `os.kill` that you entered in interactive mode, as I misinterpreted the error message. Good luck with things. Perhaps foolishly asked, but could you upgrade Python to 2.7? It appears as if the OSGeo4W folks are already testing that: http://trac.osgeo.org/osgeo4w/wiki/RequiresPython – GreenMatt Nov 22 '11 at 19:48
  • I suppose it isn't out of the question ... nice to know OSGeo4W's upgrading! – James Nov 22 '11 at 19:58

1 Answers1

2

You can do this :

import os 
import subprocess

if platform.system() == "Windows" :
    subprocess.Popen("taskkill /F /T /PID %i" % process_pid , shell=True)
else :
    os.killpg( process_pid, signal.SIGKILL)

which is cross platform. There is also a module called 'psutil':

https://github.com/giampaolo/psutil

but you should distribute your application with 32 or 64bit versions.

Giampaolo Rodolà
  • 12,488
  • 6
  • 68
  • 60
J_Zar
  • 2,034
  • 2
  • 21
  • 34