【Python网络编程和并发-多线程共享数据混乱引出同步锁】

38_第五章-多线程共享数据混乱引出同步锁

一、上节回顾

总结

  • 在一个进程内的所有线程共享全局变量,能够在部使用其他方式的前提下完成多线程之间的数据共享(这点要比多进程更好)
  • 缺点就是,线程对全局变量随意修改可能造成多线程之间对全局变量的混乱(即线程非安全)

为了解决上述问题,需要允许线程独占的访问共享数据,这就是线程的同步。需要注意的是,这些问题在进程中也是存在的,只是在多线环境下更常见而已。

有时候需要在每个线程中使用各自独立的变量,一个显而易见的方法就是每个线程都适用自己的私有变量。为了方便,Python中提供了一种简单的机制threading.local来解决这个问题。其使用方法也很简单,就是在每个线程中建立独立私有变量。

二、实操案例

1、方法1-在每个线程中建立独立的私有变量

  • 实操代码1

本方法只是逃避数据共享的操作,还需改进

在这里插入图片描述

  • 运行结果1

在这里插入图片描述

2、方法2-解决线程共享数据的混乱问题

与方法1的不同:

使用全局变量

  • 实操代码1:(每个进程的执行次数为5000)

在这里插入图片描述

  • 运行结果1(无异常)

在这里插入图片描述

  • 实操代码2:(每个进程的执行次数为500000)

在这里插入图片描述

  • 运行结果2
    在这里插入图片描述

按代码逻辑分析,每个进程执行500000次,最后的累计的g_num值应为2500000,此处出现错误

  • 实操代码2-源代码
# -*- coding:utf-8 -*-
import time
from threading import *

g_num = 0

def run():
    # print("当前进程%s,开始启动:%s"%(current_thread().name,time.time())) #开始启动时间精确到秒,这里可不打印
    print("当前进程%s,开始启动"%(current_thread().name))
    global g_num
    for i in range(500000):
        g_num += 1
    print('线程%s,执行之后g_num的值为:%s'%(current_thread().name,g_num))

if __name__ == '__main__':
    threads = []

    for i in range(5):
        t = Thread(target=run)
        t.start()
        threads.append(t)

    for j in threads:
        j.join()

    print('主线程结束,g_num的值为:%s'%g_num)
  • 小结

上面代码中出现的问题可分析如下:

(1)每个线程的运行次数设置小一些,运行的结果可能是正确的;

(2)问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破破坏使得线程运行的结果不可预期。这种现象称为“线程不安全”

解决方法:同步

同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值