简体   繁体   中英

Condition variable to pause a thread after finishing a particular task (in Python)

I am implementing a GUI for a program that builds and modifies a big graph for a bus-routing problem.

I want to have a Play-button, that should start the simulations (create a new thread simThread that executes a simulate()-method, which is pretty much an infinite loop calling a method modifyGraph() over and over again).

I also want a Pause-button, that when pressed causes the simThread to wait, but not UNTIL it has finished its current call to modifyGraph()). This is because during modifyGraph(), the graph is often in a state that shouldn't be plotted. When I press Play again, simThread should ideally continue where it was.

I am relatively new to threading in general and in Python in particular, but I have a feeling Condition Variables are the way to go. Anybody knows how to go about this?

If your simThread looks something like this:

class simThread(threading.Thread):
    def run(self):
        while True:
            modifyGraph()

You can introduce an event to unpause like this:

class simThread(threading.Thread):
    def __init__(self):
        self.unpaused = threading.Event()
        self.unpaused.set()
        threading.Thread.__init__(self)

    def run(self):
        while True:
            modifyGraph()
            unpaused.wait()

You would use this functionality like this:

thread = simThread()
thread.start()
thread.unpaused.clear()
[...]
thread.unpaused.set()

If you think an event called unpaused is a bit awkward, you can also have an additional boolean variable pause that you initially set to False . In the thread, you would check if it is True and then wait for an unpause event. So something like this:

class simThread(threading.Thread):
    def __init__(self):
        self.pause = False
        self.unpause = threading.Event()
        threading.Thread.__init__(self)

    def run(self):
        while True:
            modifyGraph()
            if self.pause:
                unpause.wait()

    def pause(self):
        self.unpause.clear()
        self.pause = True

    def unpause(self):
        self.pause = False
        self.unpause.set()

thread = simThread()
thread.start()
thread.pause()
thread.unpause()

The reason why you should use an event instead of just having another while loop spinning on self.pause is to avoid wasting CPU cycles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM