zoukankan      html  css  js  c++  java
  • 多线程-共享全局变量问题

    多线程开发可能遇到的问题

    假设两个线程t1和t2都要对全局变量g_num(默认是0)进行加1运算,t1和t2都各对g_num加10次,g_num的最终的结果应该为20。

    但是由于是多线程同时操作,有可能出现下面情况:

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

    测试1

    import threading
    import time
    
    g_num = 0
    
    def work1(num):
        global g_num
        for i in range(num):
            g_num += 1
        print("----in work1, g_num is %d---"%g_num)
    
    
    def work2(num):
        global g_num
        for i in range(num):
            g_num += 1
        print("----in work2, g_num is %d---"%g_num)
    
    
    print("---线程创建之前g_num is %d---"%g_num)
    
    t1 = threading.Thread(target=work1, args=(100,))
    t1.start()
    
    t2 = threading.Thread(target=work2, args=(100,))
    t2.start()
    
    while len(threading.enumerate()) != 1:
        time.sleep(1)
    
    print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)
    

    运行结果:

    ---线程创建之前g_num is 0---
    ----in work1, g_num is 100---
    ----in work2, g_num is 200---
    2个线程对同一个全局变量操作之后的最终结果是:200
    

    测试2

    import threading
    import time
    
    g_num = 0
    
    def work1(num):
        global g_num
        for i in range(num):
            g_num += 1
        print("----in work1, g_num is %d---"%g_num)
    
    
    def work2(num):
        global g_num
        for i in range(num):
            g_num += 1
        print("----in work2, g_num is %d---"%g_num)
    
    
    print("---线程创建之前g_num is %d---"%g_num)
    
    t1 = threading.Thread(target=work1, args=(1000000,))
    t1.start()
    
    t2 = threading.Thread(target=work2, args=(1000000,))
    t2.start()
    
    while len(threading.enumerate()) != 1:
        time.sleep(1)
    
    print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)
    

    运行结果:

    ---线程创建之前g_num is 0---
    ----in work1, g_num is 1088005---
    ----in work2, g_num is 1286202---
    2个线程对同一个全局变量操作之后的最终结果是:1286202
    

    结论

    • 如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确
  • 相关阅读:
    值类型和引用类型区别
    json数据类型
    转:不再以讹传讹,GET和POST的真正区别
    简单投票系统学到的一些东西
    jq 全选和反选以及判断那条被选中
    PHP中获取当前页面的完整URL
    jq div鼠标放上、离开马上展开、收缩方法
    js 删除确定
    mysql 存储过程
    js 闭包原理理解
  • 原文地址:https://www.cnblogs.com/georgexu/p/10909937.html
Copyright © 2011-2022 走看看