多线程-共享全局变量问题

本文讨论了多线程环境下共享全局变量可能导致的问题,如数据不准确和线程安全。介绍了同步的概念,通过设置互斥锁解决计算错误,并解释了死锁的概念。此外,还提到了Python中的queue模块在解决线程同步,特别是生产者消费者问题中的应用。
摘要由CSDN通过智能技术生成

多线程-共享全局变量问题

多线程可能遇到的问题

假设有两个线程t1和t2,都要对一个变量g_num进行运算(+1),两个线程t1和t2分别对g_num各加10次,g_num的最终结果?

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: %d"% g_num)
t1 = threading.Thread(target = work1,args = (10,))
t2 = threading.Thread(target = work2,args = (10,))

t1.start()
t2.start()

while len(threading.enumerate()) != 1:
    time.sleep(1)

print("两个线程对同一个变量操作之后的最终结果:%d"% g_num)

out

---线程创建之前g_num: 0
---in work1,g_num is  10 ---
---in work2,g_num is  20 ---
两个线程对同一个变量操作之后的最终结果:20

在num = 0时,t1 取得num = 0,此时系统把t1调度为"sleeping"的状态,t2转换为"running"的状态,t2也获得num = 0.然后,t2对得到的值进行加1 并赋给num,num = 1.

然后,系统又将t2调度为"sleeping"的状态,把t1转换为"running".线程t1又把它之前得到的0加1后赋值给num.这种情况,明明两个线程都完成了一次+1工作,但结果还是num =1.

如果我们将两个进程的参数调整为1 000 000 ,多次运行,结果不同.

说明多个线程同时对一个全局变量进行操作,会出现资源竞争问题,从而数据结果会不准确.导致线程安全问题

同步

同步,就是协同步调,按照预定的先后次序进行运行.好比交流,一个人说完,另一个人再说.

进程和线程同步,可以理解为进程或者线程A和B一块配合,A执行一定程度时需要依赖B的某个结果,于是停下来,让B运行,B开始运行,再将结果给A,A再继续操作.如此往复.直到程序结束.

计算错误的解决

通过线程同步进行解决

思路:

  • 系统调度t1,获取num = 0,此时上一把锁,即不允许其他线程操作num
  • 对num的值加1
  • 解锁,此时num的值为1,其他的线程就可以使用num了,此时num = 1
  • 同理,其他线程在对num修改时,也要先上锁,处理完后再解锁,.在上锁的过程中,不允许其他线程访问.就保证了数据的正确性.

互斥锁

当多个线程几乎同时修改某个共享数据时,需要进行同步控制

线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制就是引入互斥锁.

互斥锁为我们的资源引入一个状态:锁定/非锁定

某个线程要更改共享数据时,先将其锁定,此时,资源的状态为锁定,其他线程不能对其更改;

直到该线程释放资源资源状态变为"非锁定"状态,其他线程才能再次锁定该资源.

互斥锁,保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性.

在threading模块里,定义了Lock()类,可以方便的处理锁定.

mutex = threading.Lock(
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值