线程锁 死锁现象 递归锁 信号量 条件定时器 队列 线程池

锁是用来做什么的?
    保证数据的安全的

GIL是干什么的?
      锁线程

有了GIL还要锁干啥?

      有了GIL还是会出现数据不安全的现象,所以还是要用锁
import time
from threading import Thread,Lock
n = 100
def func(lock):
    global n
    # n -= 1
    with lock:
        tmp = n-1  # n-=1
        time.sleep(0.1)
        n = tmp

if __name__ == '__main__':
    l = []
    lock = Lock()
    for i in range(100):
        t = Thread(target=func,args=(lock,))
        t.start()
        l.append(t)
    for t in l:t.join()
    print(n)

dis模块的使用

import dis
n = 1
def func():
n = 100
n -= 1

dis.dis(func)

会出现线程不安全的两个条件
1.是全局变量
2.出现 += -=这样的操作


列表 字典
方法 l.append l.pop l.insert dic.update 都是线程安全的
l[0] += 1
d[k] += 1


死锁现象
# 科学家吃面问题
import time
from threading import Thread,Lock
# noodle_lock = Lock()
# fork_lock = Lock()
# 死锁不是时刻发生的,有偶然的情况整个程序都崩了
# 每一个线程之中不止一把锁,并且套着使用
# 如果某一件事情需要两个资源同时出现,那么不应该将这两个资源通过两把锁控制
# 而应看做一个资源
def eat1(name):
    noodle_lock.acquire()
    print('%s拿到面条了'%name)
    fork_lock.acquire()
    print('%s拿到叉子了'%name)
    print('%s开始吃面'%name)
    time.sleep(0.2)
    fork_lock.release()
    print('%s放下叉子了' % name)
    noodle_lock.release()
    print('%s放下面了' % name)

def eat2(name):
    fork_lock.acquire()
    print('%s拿到叉子了' % name)
    noodle_lock.acquire()
    print('%s拿到面条了' % name)
    print('%s开始吃面' % name)
    time.sleep(0.2)
    noodle_lock.release()
    print('%s放下面了' % name)
    fork_lock.release()
    print('%s放下叉子了' % name)

Thread(target=eat1,args=('alex',)).start()
Thread(target=eat2,args=('wusir',)).start()
Thread(target=eat1,args=('太白',)).start()
Thread(target=eat2,args=('宝元',)).start()
lock = Lock()
def eat1(name):
    lock.acquire()
    print('%s拿到面条了'%name)
    print('%s拿到叉子了'%name)
    print('%s开始吃面'%name)
    time.sleep(0.2)
    lock.release()
    print('%s放下叉子了' % name)
    print('%s放下面了' % name)

def eat2(name):
    lock.acquire()
    print('%s拿到叉子了' % name)
    print('%s拿到面条了' % name)
    print('%s开始吃面' % name)
    time.sleep(0.2)
    lock.release()
    print('%s放下面了' % name)
    print('%s放下叉子了' % name)

Thread(target=eat1,args=('alex',)).start()
Thread(target=eat2,args=('wusir',)).start()
Thread(target=eat1,args=('太白',)).start()
Thread(target=eat2,args=('宝元',)).start()
 互斥锁
# 无论在相同的线程还是不同的线程,都只能连续acquire一次
# 要想再acquire,必须先release
# 递归锁
# 在同一个线程中,可以无限次的acquire
# 但是要想在其他线程中也acquire,
# 必须现在自己的线程中添加和acquire次数相同的release

# rlock = RLock()
# rlock.acquire()
# rlock.acquire()
# rlock.acquire()
# rlock.acquire()
# print('锁不住')

# lock = Lock()
# lock.acquire()
# print('1')
# lock.acquire()
# print('2')

# rlock = RLock()
# def func(num):
#     rlock.acquire()
#     print('aaaa',num)
#     rlock.acquire()
#     print('bbbb',num)
#     rlock.release()
#     rlock.release()
#
# Thread(target=func,args=(1,)).start()
# Thread(target=func,args=(2,)).start()
import time
noodle_lock = fork_lock = RLock()
def eat1(name):
    noodle_lock.acquire()
    print('%s拿到面条了'%name)
    fork_lock.acquire()
    print('%s拿到叉子了'%name)
    print('%s开始吃面'%name)
    time.sleep(0.2)
    fork_lock.release()
    print('%s放下叉子了' % name)
    noodle_lock.release()
    print('%s放下面了' % name)

def eat2(name):
    fork_lock.acquire()
    print('%s拿到叉子了' % name)
    noodle_lock.acquire()
    print('%s拿到面条了' % name)
    print('%s开始吃面' % name)
    time.sleep(0.2)
    noodle_lock.release()
    print('%s放下面了' % name)
    fork_lock.release()
    print('%s放下叉子了' % name)

Thread(target=eat1,args=('alex',)).start()
Thread(target=eat2,args=('wusir',)).start()
Thread(target=eat1,args=('太白',)).start()
Thread(target=eat2,args=('宝元',)).start()
信号量和池
# 进程池
# 有1000个任务
# 一个进程池中有5个进程
# 所有的1000个任务会多次利用这五个进程来完成任务
# 信号量
# 有1000个任务
# 有1000个进程/线程
# 所有的1000个任务由于信号量的控制,只能5个5个的执行

import time
from threading import Semaphore,Thread

def func(name,sem):
    sem.acquire()
    print(name,'start')
    time.sleep(1)
    print(name,'stop')
    sem.release()

sem = Semaphore(5)
for i in range(20):
    Thread(target=func,args=(i,sem)).start()
定时器



猜你喜欢

转载自www.cnblogs.com/liurenli/p/10111174.html