blue01
blue01

Reputation: 2095

How to run another process in a loop on a different thread

I am creating a GUI application(wxPython). I need to run another (.exe) application from the GUI application. The subprocess will perform some operation on a user action and return an output to the GUI application

I am running this subprocess in a loop, so that constantly the subprocess is available to execute. What I am doing is, I start a thread(so gui does not freeze) and popen the subprocess in a loop. Not sure if this is the best way.

self.thread = threading.Thread(target=self.run, args=())
self.thread.setDaemon(True)
self.thread.start()

def run(self):
        while self.is_listening:
            cmd = ['application.exe']
            proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            proc.wait()
            data = ""
            while True:
                txt = proc.stdout.readline()
                    data = txt[5:].strip()
                    txt += data

Now what happens is, if the main application is shutdown, the thread is still waiting for a user action which never came. How can I exit cleanly? The application.exe process can still be seen in the process list, even after GUI app has exited. Any suggestions to improve the whole thing are welcome.

thanks

Upvotes: 5

Views: 2481

Answers (1)

Artur Gaspar
Artur Gaspar

Reputation: 4552

1) Make 'proc' a instance attribute, so you can call it's terminate() or kill() methods before exiting.

self.thread = threading.Thread(target=self.run, args=())
self.thread.setDaemon(True)
self.thread.start()

def run(self):
    while self.is_listening:
        cmd = ['application.exe']
        self.proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        self.proc.wait()
        data = ""
        while True:
            txt = self.proc.stdout.readline()
            data = txt[5:].strip()
            txt += data

2) Use some variable to tell the thread to stop (You will need to use poll() in a loop, instead of using wait()).

self.exit = False
self.thread = threading.Thread(target=self.run, args=())
self.thread.setDaemon(True)
self.thread.start()

def run(self):
    while self.is_listening:
        cmd = ['application.exe']
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        while proc.poll() is None or not self.exit:
            pass
        data = ""
        while True:
            if self.exit:
                break
            txt = proc.stdout.readline()
            data = txt[5:].strip()
            txt += data

The 'atexit' module documentation can help you with calling things at exit.

Upvotes: 2

Related Questions