MSK 发表于 2017-6-7 15:01:55

python标准库之多线程【threading】第4讲

本帖最后由 MSK 于 2017-6-7 17:05 编辑

内容概述
同步锁与递归锁,只允许一个线程访问公共资源

上一篇:
        主线程堵塞
下一篇:
        高级锁

当子线程启动时,全部线程一起执行,抢占CPU资源,有时如果大量线程同时访问一个函数,或者变量,就会出现问题。
比如:
import time
import threading

def addNum():
    global num #在每个线程中都获取这个全局变量
    # num-=1

    temp=num
    print('--get num:',num )
    #time.sleep(0.1)
    num =temp-1 #对此公共变量进行-1操作


num = 100#设定一个共享变量
thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list: #等待所有线程执行完毕
    t.join()

print('最终的数字是 :', num )

我们把这个程序执行两次:
结果为:

#C:\Users\Administrator\Desktop\课件\4>python 1.py
#--get num: 100
#--get num: 99
#--get num: 98
#--get num: 97
#--get num: 96
#省略。。。
#--get num: 5
#--get num: 4
#final num: 3

#C:\Users\Administrator\Desktop\课件\4>python 1.py
#--get num: 100
#--get num: 99
#--get num: 98
#--get num: 97
#--get num: 96
#--get num: 95
#省略。。。
#--get num: 7
#--get num: 6
#--get num: 5
#final num: 4

#C:\Users\Administrator\Desktop\课件\4>

用num -= 1则最终结果没问题,这是因为完成这个操作太快了,在线程切换时间内。用中间变量temp进行赋值时出现问题,这是因为100个线程,每一个都没有执行完就就行了切换,因此最终得到的不是0

多个线程同时操作同一个共享资源,所以导致冲突,这种情况就需要用同步锁来解决

创建锁的方法
        #实例化一个锁对象
        lock = threading.Lock()
        #开启锁
        lock.acquire()
        #解除锁
        lock.release()
       

锁保证了在调用lock.acquire()后,同一时间内只有“获得锁”的线程(先调用了lock.acquire()的线程)可以访问公共资源,其他线程被挂起,直到一个线程执行到lock.release()时解除锁,线程全部解放,下一个线程获得锁,访问公共资源,其他线程挂起。以此类推。

所以代码这样改就没问题了:
import time
import threading

def addNum():
    global num #在每个线程中都获取这个全局变量
    # num-=1
    lock.acquire()#加同步锁
    temp=num
    print('--get num:',num )
    #time.sleep(0.1)
    num =temp-1 #对此公共变量进行-1操作
    lock.release()#解锁

num = 100#设定一个共享变量
thread_list = []
lock=threading.Lock()#创建lock对象

for i in range(10):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list:#等待所有线程执行完毕
    t.join()#所有线程执行完后主程序才能结束

print('最终的数字是 :', num )


除了Lock,threading模块还提供了一种锁RLock(递归锁)
创建和使用方法差不多
lock = threading.Lock()
rlock = threading.RLock()

lock.acquire()
#do something
lock.release()

rlock.acquire()
#do something
rlock.release()

Lock 与 RLock区别
**** Hidden Message *****

{:10_302:}



hezhiqiu 发表于 2017-6-7 15:10:59

好东西,正在研究中,学习

MSK 发表于 2017-6-7 15:15:33

hezhiqiu 发表于 2017-6-7 15:10
好东西,正在研究中,学习

还会继续更新的{:5_109:}

MSK 发表于 2017-6-7 15:18:51

如果觉得有用的话可以订阅我的淘专辑,因为发帖有点散,这样学起来更方便哦{:5_91:}
你的评分是对我最大的支持!{:5_92:}

hezhiqiu 发表于 2017-6-7 15:22:09

MSK 发表于 2017-6-7 15:15
还会继续更新的

怎么订阅啊?新人刚来,啥都不懂

MSK 发表于 2017-6-7 15:49:22

hezhiqiu 发表于 2017-6-7 15:22
怎么订阅啊?新人刚来,啥都不懂

这是我的淘专辑地址:http://bbs.fishc.com/forum.php?mod=collection&action=view&ctid=654&fromop=my
点击订阅即可!{:5_109:}

hellozwh 发表于 2017-6-27 19:32:19

看看

MSK 发表于 2017-7-10 16:41:47

hellozwh 发表于 2017-6-27 19:32
看看

欢迎欢迎~

鱼粉斯 发表于 2017-9-17 19:42:17

回帖是一种美德

tuxiaoqing 发表于 2017-9-27 11:58:21

谢谢楼主分享

Brance 发表于 2017-9-28 10:23:37

看看~~

ssj5127046 发表于 2017-10-7 20:00:40

1

ephraimguo 发表于 2017-11-30 13:29:57

我就是为了看内容回帖

油滴狼 发表于 2018-1-29 14:42:27

看隐藏内容

深度 发表于 2018-1-29 19:39:44

看下这两种锁的区别

顽童鹤 发表于 2018-5-30 11:14:36

学习

syqlwzx 发表于 2018-10-31 14:59:35

看看

L所戏 发表于 2018-12-6 16:16:05

{:5_110:}

horsin 发表于 2019-1-5 22:45:29

st

tianyali8 发表于 2019-12-8 23:07:04

学习了,谢谢分享
页: [1] 2
查看完整版本: python标准库之多线程【threading】第4讲