实现一个功能,启动一个线程,只要线程不中断,就一直while true,间断10s累加某个数;
当线程线程信号时,while停止,线程退出。
- 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}")
执行结果:
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...
解释一下这段代码的意思。在主线程里面,我调用do_main_task()触发了一个任务。这个任务执行会久一些(这里设定15s)。但是这个任务完成以后,会有个返回值,告诉我完成了。另外创建一个 add_task 子线程,每10秒累加10。
但某些情况下,我不需要等待了,例如用户主动取消了任务。这个时候,我就想提前结束这个 add_task 子线程。
通过执行结果可以看出,当执行一次+10,等待10s后,又过了5秒,主线程do_main_task结束了,这时add_task线程还在累加的sleep(10)中没有退出。主线程执行结果已经是sum=10,再过5秒后add_task线程才结束。
但是,线程是不能从外面主动杀死的,只能让它自己退出。
应用threading模块里面的Event,
用法和sleep差不多:
- import threading
-
- event = threading.Event()
- event.wait(5)
上述例子可以这样实现:
- 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}")
执行结果:
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
当执行event.set()后,子线程里面self.event.is_set()就会返回 False,于是这个循环就不会继续执行了。
即使self.event.wait(10)刚刚开始阻塞,只要我在主线程中执行了event.set(),子线程里面的阻塞立刻就会结束。于是子线程立刻就会结束。不需要再白白等待10秒。
并且,event.wait()这个函数在底层是使用 C 语言实现的,不受 GIL 锁的干扰。