python锁_Python-锁

一. Python线程互斥锁Lock

使用多线程可以同时执行多个任务,提高开发效率,但是在实际开发中往往我们会碰到线程同步问题,假如有这样一个场景:对全局变量累加1000000此,为了提高开发效率,我们可以使用多线程完成,示例代码如下:

#!/usr/bin/python

#-*- coding: utf-8 -*-# 导入线程threading模块

import threading

# 声明全局变量

g_num= 0def my_thread1():

# 声明全局变量globalg_num

# 循环1000000 次,每次累计加 1

for i in range(0, 1000000):

g_num= g_num + 1def my_thread2():

# 声明全局变量globalg_num

# 循环1000000 次,每次累计加 1

for i in range(0, 1000000):

g_num= g_num + 1def main():

# 声明全局变量globalg_num

# 初始化全局变量,初始值为0# 创建两个线程,对全局变量进行累计加1t1= threading.Thread(target=my_thread1)

t2= threading.Thread(target=my_thread2)

# 启动线程

t1.start()

t2.start()

# 阻塞函数,等待线程结束

t1.join()

t2.join()

# 获取全局变量的值

print("计算结果:%d" %(g_num))if __name__ == "__main__":

main()

执行结果:

cdf6c46f3c4d906e8b05e77189c85a7e.png

这个是什么操作?看着代码好像也没问题,两个线程,各自累加1000000次,不应该输出的是2000000吗?

1. 线程共享全局变量

分析上面的代码:两个线程共享全局变量并执行for循环1000000,每次自动加1,我们都知道两个线程都是在同时运行,也就是说两个线程同时在执行g_num = g-num = 1操作,经过我们冷静分析一波,貌似结果该是应该等于2000000,对不对?

首先我们将上面的全局变量自动加1的代码分为两步:

第一步: g_num + 1

第二步: 将g_num + 1的结果赋值给g_num

由此可见,执行一个完整的自动加1的过程需要两步,然而线程确是同时在运行,谁也不能保证线程1的第一步和第二部执行完成之后才执行线程2的第一步和第二步,执行的过程充满随机性,这就是导致每次计算结果不同的原因所在。

2. 线程互斥锁

为了避免上面的问题,我们可以利用线程互斥锁解决这个问题,那么线程互斥锁到底是个什么原理呢?互斥锁就好比排队上厕所,一个坑位只能蹲一个人,只有占用坑位的人完事了,另一个人才能上!!

4e8290aadc72bac5419fd22eb5b01127.png

创建互斥锁

导入线程模块,通过threading.Lock()创建互斥锁

import threading

mutex= threading.Lock()

锁定资源/解锁资源

acquire() --锁定资源,此时资源是锁定状态,其他线程无法修改锁定的资源,知道等待锁定的资源释放之后才能操作

release() --释放资源,也成为解锁操作,对锁定的资源解锁,解锁之后其他线程可以对资源正常操作

上面的代码为例子:想得到正确的结果,可以直接利用互斥锁在全局变量加1之前锁定资源,然后在计算完成之后释放资源,这样就是一个完整的计算过程,至于应该是那个线程先执行,无所谓,先到先得,凭本事说话

#!/usr/bin/python

#-*- coding: utf-8 -*-# 导入线程threading模块

import threading

mutex=threading.Lock()

# 声明全局变量

g_num= 0def my_thread1():

# 声明全局变量globalg_num

# 循环1000000 次,每次累计加 1

for i in range(0, 1000000):

mutex.acquire()

g_num= g_num + 1mutex.release()

def my_thread2():

# 声明全局变量globalg_num

# 循环1000000 次,每次累计加 1

for i in range(0, 1000000):

mutex.acquire()

g_num= g_num + 1mutex.release()

def main():

# 声明全局变量globalg_num

# 初始化全局变量,初始值为0# 创建两个线程,对全局变量进行累计加1t1= threading.Thread(target=my_thread1)

t2= threading.Thread(target=my_thread2)

# 启动线程

t1.start()

t2.start()

# 阻塞函数,等待线程结束

t1.join()

t2.join()

# 获取全局变量的值

print("计算结果:%d" %(g_num))if __name__ == "__main__":

main()

执行结果:

2dd3b62ffdf28eb6f7c76cd5389f6d34.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值