想象这样一个场景:你创建10个子线程,每个子线程分别爬取一个网站。一开始,所有子线程都阻塞等待。一旦某个事件发生:比如有人在网页上点击了一个按钮,或者有人在命令行输入了一条命令,10个爬虫同时开始工作。肯定有人会想到用Redis来实现这个开关:所有子线程监听Redis中名为start_crawl的字符串。如果这个字符串不存在或者为0,那么等待1秒再继续检查。如果此字符串为1,则开始运行。代码片段可以简写为:importtimeimportredisclient=redis.Redis()whileclient.get('start_crawl')!=1:print('continuetowait')time.sleep(1)这样确实可以达到目的,但是每次子线程Redis会经常检查。其实在Python的多线程中,有一个Event模块,自然就是用来达到这个目的的。事件是一个可以在多个线程中共享的对象。一开始,它包含一个False信号标志。一旦在任何线程中将标志更改为True,所有线程都会看到该标志已变为True。.我们用一段代码来说明它的用法:'{self.n}爬虫就位!')self.event.wait()print(f'信号变为True!!{self.n}爬虫开始运行')eve=threading.Event()fornuminrange(10):crawler=spider(num,eve)crawler.start()input('按回车键启动所有爬虫!')eve.set()time.sleep(10)运行效果如下图所示:在这段代码,threadspider运行后,会运行到self.event.wait()这一行,然后10个子线程都会被阻塞在这里。这里的self.event是主线程中eve=threading.Event()生成的对象传入的。在主线程中,执行eve.set()时,所有子线程会同时解除阻塞,子线程才能继续运行。本文转载自微信公众号“闻所未闻的密码”,可通过以下二维码关注。转载本文请联系Code公众号。
