Detailed explanation and examples of the suspension, recovery, and exit of python threads
python thread pause, resume, exit
We all know that the threading module can implement multi-threading in python, but the module does not provide methods for suspending, resuming and stopping threads. Once the thread object calls the start method, it can only wait until the corresponding method function is completed. That is to say, once start After that, the thread is out of control. However, we can implement these by ourselves. The general method is to judge a flag bit in a loop, and once the flag bit reaches a predetermined value, it will exit the loop. In this way, the thread can be exited. But Pausing and resuming threads is a bit difficult, and I haven’t been able to clear any good methods until I saw the description of the wait method of the Event object in threading.
wait([timeout])
Block until the internal flag is true. If the internal flag is true on entry, return immediately. Otherwise, block until another thread calls set() to set the flag to true, or until the optional timeout occurs.
When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof).
This method returns the internal flag on exit, so it will always return True except if a timeout is given and the operation times out.
Changed in version 2.7: Previously, the method always returned None.
Using the blocking mechanism of wait, you can realize pause and resume, and then cooperate with the loop judgment flag to realize the exit. The following is a code example:
#!/usr/bin/env python
# coding: utf-8
import threading
import time
class Job(threading.Thread):
def __init__(self, *args, **kwargs):
super(Job, self).__init__(*args, **kwargs)
self.__flag = threading.Event() # The flag used to suspend the thread
self.__flag.set() # set to True
self.__running = threading.Event() # ID used to stop the thread
self.__running.set() # set running to True
def run(self):
while self.__running.isSet():
self.__flag.wait() # Returns immediately when True, blocks when False until the internal flag is True and returns
print time.time()
time.sleep(1)
def pause(self):
self.__flag.clear() # Set to False to block the thread
def resume(self):
self.__flag.set() # Set to True to stop the thread from blocking
def stop(self):
self.__flag.set() # Resume the thread from the suspended state, if it has been suspended
self.__running.clear() # set to False
Here is the test code:
a = Job()
a.start()
time.sleep(3)
a.pause()
time.sleep(3)
a.resume()
time.sleep(3)
a.pause()
time.sleep(2)
a.stop()
The result of the test is that the functions of suspending, resuming and stopping are completed. But there is a disadvantage here: whether it is suspending or stopping, it is not instantaneous, and it must wait for the operation inside the run function to reach the flag bit before it is valid. That is, the operation will lag once.
But this is sometimes not necessarily a bad thing. If the run function involves file operations or database operations, etc., run it once before exiting, and instead can execute the code for the remaining resource release operations (such as various closes). It will not appear. The program’s file operator exceeds the upper limit, the database connection is not released, etc.