问题:已经有了全局解释器锁为什么还需要锁?
答:全局解释器锁是在Cpython解释器下,同一时刻,多个线程只能有一个线程被cpu调度
它是在线程和cpu之间加锁,线程和cpu之间有传递时间,即使有GIL,也无法保证数据的绝对安全
锁的分类
1、互斥锁
2、死锁
3、递归锁
# 虽然有全局解释器锁,数据仍然出现了安全问题 from threading import Thread import time def test(): global n temp = n time.sleep(1) n = temp - 1 n = 10 t_li = [] for i in range(5): t = Thread(target=test) t_li.append(t) t.start() [t.join() for t in t_li] print(n) # 9
互斥锁
# 使用锁,解决了数据安全问题 from threading import Thread, Lock import time def test(lock): lock.acquire() global n temp = n time.sleep(1) n = temp - 1 lock.release() n = 10 lock = Lock() t_li = [] for i in range(5): t = Thread(target=test, args=(lock, )) t_li.append(t) t.start() [t.join() for t in t_li] print(n) # 5
死锁
# 科学家吃面 from threading import Lock from threading import Thread import time noddle = Lock() chopsticks = Lock() def test1(name): noddle.acquire() print('%s拿到面条' % name) # time.sleep(2) chopsticks.acquire() print('%s拿到筷子' % name) print('%s吃面' % name) # time.sleep(1) chopsticks.release() noddle.release() def test2(name): chopsticks.acquire() print('%s拿到筷子' % name) time.sleep(0.3) noddle.acquire() print('%s拿到面条' % name) print('%s吃面' % name) noddle.release() chopsticks.release() t1 = Thread(target=test1, args=('tom', )) t1.start() t2 = Thread(target=test2, args=('abc', )) t2.start() t3 = Thread(target=test1, args=('joker', )) t3.start() t4 = Thread(target=test2, args=('ff', )) t4.start()
递归锁
# 递归锁,多个acquire()不会造成死锁 from threading import RLock from threading import Thread a = RLock() def test(): a.acquire() a.acquire() a.acquire() print('hello, world') Thread(target=test).start()
# 科学家吃面 递归锁 from threading import RLock from threading import Thread import time noddle = chopsticks = RLock() def test1(name): noddle.acquire() print('%s拿到面条' % name) # time.sleep(2) chopsticks.acquire() print('%s拿到筷子' % name) print('%s吃面' % name) # time.sleep(1) chopsticks.release() noddle.release() def test2(name): chopsticks.acquire() print('%s拿到筷子' % name) time.sleep(0.3) noddle.acquire() print('%s拿到面条' % name) print('%s吃面' % name) noddle.release() chopsticks.release() t1 = Thread(target=test1, args=('tom', )) t1.start() t2 = Thread(target=test2, args=('abc', )) t2.start() t3 = Thread(target=test1, args=('joker', )) t3.start() t4 = Thread(target=test2, args=('ff', )) t4.start()