3

前天才讲的知识点,不听讲的人今天就跑来问

 3 years ago
source link: https://www.kingname.info/2021/04/05/thread-event/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前天才讲的知识点,不听讲的人今天就跑来问

发表于

2021-04-05

|

更新于 2021-05-14

| 分类于 Python

| 评论数: 0

今天在读者交流群里面,有同学提到这样一个问题:

2021-04-06-20-32-34.png

2021-04-06-20-32-51.png

这个同学想实现,在代码第35行,如果进入了 if 判断,那么就退出第40-43行对应的 ac 函数。

能问出这个问题,说明这个同学显然没有认真看我的微信公众号。就在几天前我才发了一篇文章:一日一技:Python多线程的事件监控。使用这篇文章里面讲到的方法,就可以轻易实现他的需求。

在那篇文章中,我们讲到了threading.Event,这个东西不仅可以在线程之间使用,也可以在主线程和子线程之间使用。

这个同学的代码不够清晰,我们稍稍修改一下:

import time
import threading
import datetime

class Monitor(threading.Thread):
def __init__(self, endtime):
super().__init__()
print('ac 函数将会在:', endtime, '停止')
self.endtime = endtime

def run(self):
while True:
now = datetime.datetime.now()
if now > self.endtime:
print('结束主线程')
# TODO: 这里需要做点什么事情
time.sleep(1)

def ac():
while True:
print('主线程正在运行,现在时间', datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
time.sleep(5)


if __name__ == '__main__':
stop_time = datetime.datetime.now() + datetime.timedelta(seconds=60)
monitor = Monitor(stop_time)
monitor.start()
ac()

如果你直接运行上面这段代码,你会发现程序每5秒钟会通过ac函数打印一条字符串,但永远不会停止。现在,我们在 需要在#TODO的位置怎么写代码,才能让程序停止呢?这个时候,我们把threading.Event引入进来。在外面生成并传给子线程:

import time
import threading
import datetime

class Monitor(threading.Thread):
def __init__(self, endtime, event):
super().__init__()
self.endtime = endtime
print('ac 函数将会在:', endtime, '停止')
self.event = event

def run(self):
while True:
now = datetime.datetime.now()
if now > self.endtime:
print('结束主线程')
self.event.set()
return
time.sleep(1)

def ac(event):
while not event.is_set():
print('主线程正在运行,现在时间', datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
time.sleep(5)


if __name__ == '__main__':
event = threading.Event()
stop_time = datetime.datetime.now() + datetime.timedelta(seconds=60)
monitor = Monitor(stop_time, event)
monitor.start()
ac(event)

运行效果如下图所示:

2021-04-06-20-59-47.png

当子线程检测到满足结束条件的时候,调用event.set()。主线程里面,ac函数使用一个循环不停检测event.is_set()。一开始event.is_set()始终返回 False,直到event.set()以后,就返回 True。这样一来,ac函数就像是收到了通知,于是可以结束函数的运行了。

如果大家有任何编程上的问题,可以进入未闻 Code 读者交流微信群提问。目前交流群一群、二群已经慢了,三群正在等待更多同学的加入。加我微信号mekingname,备注粉丝群就可以进入。

谢乾坤 | Kingname wechat
第一时间获取最新文章更新,请订阅我的微信公众号:未闻Code

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK