多线程的时候,我们会用到同步与互斥。一般是获取互斥锁,其余的线程就会陷入阻塞。但是在协程中,可能出现栈帧切换之后重新获取锁的问题,这时候能获取成功吗?
答案分情况而论,如果是可重入锁,是可以获取成功的,原因可以看可重入锁的定义。
A reentrant lock is a synchronization primitive that may be acquired multiple times by the same thread.
也就是说,内核对于锁属主的判别是基于线程ID的,不要妄想用可重入锁避开不同协程间的资源争用问题。
# coding=utf-8
import threading
lock = threading.RLock()
def consumer():
x = yield 11
lock.acquire()
y = yield x * x
z = yield y * y
lock.release()
def producer():
c = consumer()
print(next(c))
lock.acquire()
print(c.send(11))
print(c.send(22))
lock.release()
if __name__ == '__main__':
producer()
当然,如果采用不可重入锁,这个就更糟糕了,直接就导致所有的协程死掉了。
理论上,操作系统的锁机制可以理解为余量为1的信号量即可,获取和占用都要识别线程ID。
网友评论