Control a python thread from outside

2019-08-17 07:50发布

问题:

I have a program, which needs to continuously run in the background, but be able to receive instructions to change. I have this thread running, which sends data to an Arduino and receives data back:

class receiveTemp (threading.Thread):
    def __init__(self, out):
        threading.Thread.__init__(self)
        self.out = out

    def run(self):
        self.alive = True
        try:
            while self.alive:
                rec = send("command")
                self.out.write(rec)
        except BaseException as Error:
            print(Error)
            pass

Now I need to change the command I send with an external program.
I tried using Pyro4, but I can not seem to get a Thread running on the server and then controlling it with the client.

Any ideas?

回答1:

Scott Mermelstein's advice is good, I hope you will look into interprocess communications. But as a quick example to get you started, I would suggest modifying your code like this:

import threading
import queue
import sys
import time

class receiveTemp (threading.Thread):
    def __init__(self, out, stop, q):
        threading.Thread.__init__(self)
        self.out = out
        self.q = q
        self.stop = stop

    def run(self):
        while not self.stop.is_set():
            try:
                cmd = self.q.get(timeout=1)
            except queue.Empty:
                continue
            try:
                rec = send(cmd)
                self.out.write(rec)
            except BaseException as Error:
                print(Error)
                pass

stop = threading.Event()
q = queue.Queue()

rt = receiveTemp(sys.stdout, stop, q)
rt.start()

# Everything below here is an example of how this could be used.
# Replace with your own code.
time.sleep(1)
# Send commands using put.
q.put('command0')
q.put('command1')
q.put('command2')
time.sleep(3)
q.put('command3')
time.sleep(2)
q.put('command4')
time.sleep(1)
# Tell the thread to stop by asserting the event.
stop.set()
rt.join()
print('Done')

This code uses a threading.Event as a signal to the thread that it should stop. It then uses a queue.Queue as a way to send commands to the thread from outside. You will need to use q.put(command) to add commands to the queue from outside the thread.

I didn't test this with an Arduino, I created my own version of send for testing that just returned the command.