Detailed explanation and examples of the suspension, recovery, and exit of python threads

Alibaba Cloud
3 min readJan 21, 2022

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.

Original Source:

--

--

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com