python爬虫-23-python多线程详解(2)继承类,以及多线程锁

网友投稿 703 2022-11-06

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

python爬虫-23-python多线程详解(2)继承类,以及多线程锁

1、python之多线程threading封装为了让线程代码更好的封装。可以使用threading模块下的Thread类,继承自这个类,然后实现run方法,线程就会自动运行run方法中的代码。我们可以将上一篇的代码进行封装,封装之后的代码:import threadingfrom datetime import datetimeimport timeclass Eating(threading.Thread):    def run(self):        for i in range(3):            print("正在吃第{}顿饭\n".format(i))            time.sleep(1)class Studying(threading.Thread):    def run(self):        for i in range(3):            print("运维家{}颗心\n".format(i))            time.sleep(1)def Total():    Start = datetime.now()    T1 = Eating()    T2 = Studying()    T1.start()    T2.start()    T1.join()    T2.join()    Stop = datetime.now()    Total_time = Stop - Start    print("该代码运行时间为:{}".format(Total_time))if __name__ == '__main__':    Total()运行结果如下:正在吃第0顿饭运维家0颗心运维家1颗心正在吃第1顿饭运维家2颗心正在吃第2顿饭该代码运行时间为:0:00:03.014794我们可以看到,通过重写python的threading.Thread的run方法,我们也成功的实现了多线程,且更加优雅。2、threading之锁机制我们想一个问题哈,当你这个代码中有一个全局变量A 同时被两个线程进行调用的时候,我们该如何保证这个变量保持一个先后顺序来被调用呢,因为当你启动了两个线程之后,我们是无法控制线程的运行顺序的,那么在这样子的前提下,是不是就存在那么一种数据错乱的可能性呢。例如,当全局变量A被线程C调用的时候,线程D也来调用全局变量A 了,那么此时是不是全局变量A就有可能发生变化,在这种情况下,当线程C再次来调用全局变量A的时候,数据是不是就不准了呀,我们来简单看个例子吧:import threadingA = 0def Thread_C():    global A    for c in range(1000000):        A += 1    print(A)def Thread_D():    global A    for d in range(1000000):        A += 1    print(A)def main():    T1 = threading.Thread(target=Thread_C)    T2 = threading.Thread(target=Thread_D)    T1.start()    T2.start()    T1.join()    T2.join()if __name__ == '__main__':    main()运行之后输出结果如下:13028441717930可以看到两个输出内容,一个是1302844,另一个是1717930,当我们再次运行的时候,这个结果会再次发生变化;但是正常逻辑来说呢,他应该输出一个1000000和一个2000000,对吧,其实这种情况在数量较少的情况下是有可能不会有问题的,因为在你第二个线程还没有启动的时候,第一个线程就已经执行完了,所以数量少的情况下,就有可能没问题。那么这个情况,就是没有给变量上锁,导致多个线程同时调用一个可变的全局变量,导致的该问题;python也给我们提供了解决方法,就是当有这种情况发生的时候,我们通过给某个线程访问某个变量的时候上锁,确保该线程在调用某个变量的时候,其他线程无法访问进行,让其处于等待状态,直到该线程处理完毕,将锁释放,该变量才会被其他线程调用,那么这种情况就不会有上面的情况出现了,我们看下如何实现吧。方法:threading.Lock()代码:import threadingA = 0A_Lock = threading.Lock()  # 创建锁def Thread_C():    global A    A_Lock.acquire()  # 上锁    for c in range(1000000):        A += 1    A_Lock.release()  # 解锁    print(A)def Thread_D():    global A    A_Lock.acquire()  # 上锁    for d in range(1000000):        A += 1    A_Lock.release()  # 解锁    print(A)def main():    T1 = threading.Thread(target=Thread_C)    T2 = threading.Thread(target=Thread_D)    T1.start()    T2.start()    T1.join()    T2.join()if __name__ == '__main__':    main()运行结果如下:10000002000000我们可以看到,当我们上锁之后,就获得了正确的值。当然了,上面这个示例有点儿极端,虽然说当你计算数量较少的情况下,问题可能不大,但是还是推荐有类似的情况,统一加锁吧。至此,本文结束,相关内容每日更新。

往期推荐python爬虫-16-python之正则表达式,以最快的速度获取有效数据(上)python爬虫--10-使用python爬取豆瓣正在上映的电影python爬虫-04-如何爬取网易云音乐的歌曲,再认识urllib模块

上一篇:软件测试培训之网页测试的测试类型
下一篇:软件测试培训之网站测试技术要领
相关文章

 发表评论

暂时没有评论,来抢沙发吧~