zoukankan      html  css  js  c++  java
  • 【Python3 爬虫】U25_多线程爬虫之多线程共享全局变量及锁机制

    1.共享全局变量

    1.1 共享全局变量问题

    在一个进程内的所有线程共享全局变量,很方便在多个线程之间共享数据,但是存在一个缺点,当线程无序执行的时候,会导致全局变量的混乱,导致数据错误。
    例如:
    假设两个线程t1和t2都要对全局变量g_num(默认是0)进行加1运算,t1和t2都各对g_num加10次,g_num的最终的结果应该为20。
    但是由于是多线程同时操作,有可能出现下面情况:

    • 在g_num=0时,t1取得g_num=0。此时系统把t1调度为"sleeping"状态,把t2转换为"running"状态,t2也获得g_num=0
    • 然后t2对得到的值进行加1并赋给g_num,使得g_num=1
    • 然后系统又把t2调度为”sleeping”,把t1转为”running”。线程t1又把它之前得到的0加1后赋值给g_num。
    • 这样导致虽然t1和t2都对g_num加1,但结果仍然是g_num=1

    1.2 示例

    import threading
    num = 0
    
    def get_num():
        global num
        for i in range(1000000):
            num += 1
        print("num的值为:%d" %num)
    
    def main():
        # 启动2个线程对执行函数get_num
        for x in range(2):
            t = threading.Thread(target=get_num)
            t.start()
       
    if __name__ == '__main__':
        main()
    

    本次执行结果:(每次执行结果都不一样)
    num的值为:1104111
    num的值为:1185898

    从上述结果可以看到,两次的和按照常理来说应该是2000000,但实际却不是,说明出现了线程安全问题。

    3.锁机制

    对于上述问题,结论是:如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确
    那么如何来解决这个问题呢?
    我们可以将上述函数的调用加上一把锁,比如线程1准备执行这个函数,那么先把这个函数锁起来,此时,就不允许其他线程来操作,如果要操作,不好意思,得等我执行完,不然,没门。这样就可以保证每次执行函数的时候,全局变量不会同时被2个线程拿到,就解决了资源争夺问题了。下面是具体的代码示例:

    import threading
    num = 0
    g_lock = threading.Lock()
    def get_num():
        global num
        g_lock.acquire()
        for i in range(1000000):
            num += 1
        g_lock.release()
        print("num的值为:%d" %num)
    
    def main():
        # 启动2个线程对执行函数get_num
        for x in range(2):
            t = threading.Thread(target=get_num)
            t.start()
    
    if __name__ == '__main__':
        main()
    

    执行结果:

    num的值为:1000000
    num的值为:2000000

  • 相关阅读:
    中国百年校服史:青春飞扬的几代人[转]
    关于五笔和拼音输入法的最本质区别
    Windows Mobile device 开发详解..
    生成目录树
    安装CE 6.0和VS2005出现的两个问题解决
    在c与c++下struct的区别,已经在c++下struct与class的区别。
    一招克死所有病毒!上网不用防火墙.不看后悔哟
    VC解析XML文件
    pythonday1笔记
    an error occurred while completing process java.lang.reflect.InvocationTargetEx
  • 原文地址:https://www.cnblogs.com/OliverQin/p/12632095.html
Copyright © 2011-2022 走看看