Scenario description:
Realize a function, start a thread, as long as the thread is not interrupted, it will always be while true, accumulating a certain number intermittently for 10s;
When the thread thread signals, the while stops and the thread exits.
1. Method one time.sleep
import time
from threading import Thread
class AddTask(Thread):
def __init__(self):
super().__init__()
self.sum_num = 0
self._button = True
def run(self):
print('Begin to add ...')
while self._button:
print('Sleep start...')
time.sleep(10)
print('Sleep end...')
self.sum_num += 10
print(f"Finish add, sum:{self.sum_num}...")
def stop(self):
print('Stop task...')
self._button = False
def do_main_task():
print('Do main task...')
time.sleep(15)
print('Finish main task...')
return True
if __name__ == '__main__':
add_task = AddTask()
add_task.start()
main_task_end = do_main_task()
if main_task_end:
add_task.stop()
time.sleep(1)
print(f"sum: {add_task.sum_num}")
Results of the:
Begin to add ...Do main task...
Sleep start...
Sleep end...
Sleep start...
Finish main task...
Stop task...
sum: 10
Sleep end...
Finish add,sum: 20...
Explain what this code means. Inside the main thread, I call do_main_task ()
to trigger a task. This task will take longer to execute (15s is set here). But after this task is completed, there will be a return value telling me that it is completed. In addition, create an add_task sub-thread, adding 10 every 10 seconds.
But in some cases, I don't need to wait, for example, the user actively canceled the task. At this time, I want to end this add_task sub-thread early.
It can be seen from the execution results that when +10 is executed once, after waiting for 10s, and after another 5 seconds, the main thread do_main_task ends, and the add_task thread is still in the accumulated sleep (10) and has not exited. The execution result of the main thread is already sum=10, and the add_task thread will end after another 5 seconds.
However, the thread cannot be actively killed from the outside, it can only be allowed to exit by itself.
2. Method 2 event.wait
应用threading
inside the moduleEvent,
用法和sleep差不多:
import threading
event = threading.Event()
event.wait(5)
The above example can be implemented like this:
import time
from threading import Thread
from threading import Event
class AddTask(Thread):
def __init__(self):
super().__init__()
self.sum_num = 0
self.event = Event()
def run(self):
print('Begin to add ...')
while not self.event.is_set():
print('Sleep start...')
self.event.wait(10)
print('Sleep end...')
self.sum_num += 10
print(f"Finish add, sum:{self.sum_num}...")
def stop(self):
print('Stop task...')
self.event.set()
def do_main_task():
print('Do main task...')
time.sleep(15)
print('Finish main task...')
return True
if __name__ == '__main__':
add_task = AddTask()
add_task.start()
main_task_end = do_main_task()
if main_task_end:
add_task.stop()
time.sleep(1)
print(f"sum: {add_task.sum_num}")
Results of the:
Do main task...
Begin to add ...
Sleep start...
Sleep end...
Sleep start...
Finish main task...
Stop task...
Sleep end...
Finish add, sum:20...sum: 20
When executed event.set()
, False will be returned in the child thread self.event.is_set()
, so the loop will not continue to execute.
即使self.event.wait(10)
Just started blocking, as long as I execute it in the main thread event.set()
, the blocking in the sub-thread will end immediately. So the child thread will end immediately. No need to wait 10 seconds in vain.
Moreover, event.wait()
this function is implemented in C language at the bottom, without interference from GIL locks.