pyhton 线程锁

问题:已经有了全局解释器锁为什么还需要锁?

答:全局解释器锁是在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()

 

posted @ 2019-06-22 15:45  市丸银  阅读(168)  评论(0编辑  收藏  举报