Python并发编程之谈谈线程中的“锁机制”(三)
大家好,并发编程
进入第三篇。
今天我们来讲讲,线程里的锁机制
。
本文目录
- 何为Lock( 锁 )?
- 如何使用Lock( 锁 )?
- 为何要使用锁?
- 可重入锁(RLock)
- 防止死锁的加锁机制
- 饱受争议的GIL(全局锁)
. 何为Lock( 锁 )?
何为 Lock
( 锁 ),在网上找了很久,也没有找到合适的定义。可能 锁
这个词已经足够直白了,不需要再解释了。
但是,对于新手来说,我还是要说下我的理解。
我自己想了个生活中例子来看下。
有一个奇葩的房东,他家里有两个房间想要出租。这个房东很抠门,家里有两个房间,但却只有一把锁,不想另外花钱是去买另一把锁,也不让租客自己加锁。这样租客只有,先租到的那个人才能分配到锁。X先生,率先租到了房子,并且拿到了锁。而后来者Y先生,由于锁已经已经被X取走了,自己拿不到锁,也不能自己加锁,Y就不愿意了。也就不租了,换作其他人也一样,没有人会租第二个房间,直到X先生退租,把锁还给房东,可以让其他房客来取。第二间房间才能租出去。
换句话说,就是房东同时只能出租一个房间,一但有人租了一个房间,拿走了的锁,就没有人再在租另一间房了。
回到我们的线程中来,有两个线程A和B,A和B里的程序都加了同一个锁对象,当线程A率先执行到lock.acquire()(拿到全局的锁后),线程B只能等到线程A释放锁lock.release()后(归还锁)才能运行lock.acquire()(拿到全局的锁)并执行后面的代码。
这个例子,是不是让你清楚了什么是锁呢?
. 如何使用Lock( 锁 )?
来简单看下代码,学习如何加锁,获取钥匙,释放锁。
需要注意的是,lock.acquire()
和 lock.release()
必须成对出现。否则就有可能造成死锁。
很多时候,我们虽然知道,他们必须成对出现,但是还是难免会有忘记的时候。
为了,规避这个问题。我推荐使用使用上下文管理器来加锁。
with
语句会在这个代码块执行前自动获取锁,在执行结束后自动释放锁。
. 为何要使用锁?
你现在肯定还是一脸懵逼,这么麻烦,我不用锁不行吗?有的时候还真不行。
那么为了说明锁存在的意义。我们分别来看下,不用锁的情形有怎样的问题。
定义两个函数,分别在两个线程中执行。这两个函数 共用
一个变量 n
。
看代码貌似没什么问题,执行下看看输出
job1 1
job1 2
job1 job2 13
job2 23
job2 333
job1 34
job1 35
job2
job1 45 46
job2 56
job1 57
job2
job1 67
job2 68 78
job1 79
job2
job1 89
job2 90 100
job2 110
相关文章