协程与同步原语

多线程的时候,我们会用到同步与互斥。一般是获取互斥锁,其余的线程就会陷入阻塞。但是在协程中,可能出现栈帧切换之后重新获取锁的问题,这时候能获取成功吗?
答案分情况而论,如果是可重入锁,是可以获取成功的,原因可以看可重入锁的定义。

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。

你可能感兴趣的:(协程与同步原语)