#一.锁
# 线程安全:多线程操作时,内部会让所有的线程排队处理(列表,字典,queue)
# 线程不安全+锁=>排队处理
#1.lock(锁一段区域)一次放行一个
# 需求
# 把自己添加到列表中
# 读取列表的最后一个值
# import threading
# import time
# v=[]
# def func(arg):
# v.append(arg)
# time.sleep(0.01)
# m=v[-1]
# print(arg,m)
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
# 1 9
# 3 9
# 0 9
# 2 9
# 5 9
# 4 9
# 7 9
# 6 9
# 8 9
# 9 9
# import threading
# import time
# v=[]
# lock=threading.Lock()
# def func(arg):
# lock.acquire() #获得锁
# v.append(arg)
# time.sleep(0.01)
# m=v[-1]
# lock.release() #释放锁
# print(arg,m)
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
# 0 0
# 1 1
# 2 2
# 3 3
# 4 4
# 5 5
# 6 6
# 7 7
# 8 8
# 9 9
#2.RLock(与Lock用法相同,但是Lock不支持锁多次解多次,RLock支持)一次放行一个
# import threading
# import time
# v=[]
# lock=threading.RLock()
# def func(arg):
# lock.acquire()
# lock.acquire()
# v.append(arg)
# time.sleep(0.01)
# m=v[-1]
# lock.release()
# lock.release()
# print(arg,m)
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
#3.BoundedSemaphort(一次放n个)信号量
# import threading
# import time
# lock=threading.BoundedSemaphore(3) #可以有三个线程同时通过锁
# def func(arg):
# lock.acquire()
# print(arg)
# time.sleep(2)
# lock.release()
#
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
#4.Condition(一次放不定数量个,由用户动态指定)
# 用法一:
# import threading
# import time
# lock=threading.Condition()
# def func(arg):
# print('线程进来了')
# lock.acquire() #也需要acquire和release
# lock.wait() #在wait处加锁
# print(arg)
# lock.release()
#
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
# while 1:
# inp=int(input('请输入需要输出的数量:'))
# lock.acquire() #以下三行必须要有
# lock.notify(inp)
# lock.release()
# 用法二:
# import threading
# lock=threading.Condition()
# def xxx():
# print('来执行函数了')
# return input('>>>')
# def func(arg):
# print('线程进来了')
# lock.wait_for(xxx) #锁住了,等括号中的 xxx成立了,再释放锁
# print(arg)
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
#5.Event(一次放所有)
# import threading
# import time
# lock=threading.Event() #可以有三个线程同时通过锁
# def func(arg):
# print('线程来了')
# lock.wait() #加锁
# print(arg)
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
# input('>>>')
# lock.set() #遇到这句就所有的都放过去了,此时的lock.wait变成了释放锁的状态
# lock.clear() #lock.wait又变成了加锁的状态
#
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
# time.sleep(3)
# input('>>>>')
# lock.set() #再次释放锁
#6.threading.local
# import threading
# import time
# v=threading.local()
# def func(arg):
# #内部会为当前线程创建一个空间用于存储
# v.phone=arg
# time.sleep(2)
# print(v.phone,arg)
#
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
# import threading
# import time
#
# DATA_DICT={}
# v=threading.local()
# def func(arg):
# # c=threading.current_thread()
# # print(c,arg)
# v=threading.get_ident()
# DATA_DICT[v]=arg
# # print(v,arg)
#
# time.sleep(1)
# print(DATA_DICT[v],arg)
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
#原理:#内部会为每个线程创建一个空间(字典),用于当前线程存取属于自己的值,保证线程之间的数据隔离
# import threading
# import time
# INFO={}
# class Local(object):
# # def __getattr__(self, item):
# # ident=threading.get_ident()
# # return [ident][item]
# def __setattr__(self, key, value):
# ident=threading.get_ident()
# if ident in INFO:
# INFO[ident][key]=value
# else:
# INFO[ident]={key:value}
# INFO[ident]['mi'] = 10
# obj=Local()
# def func(arg):
# obj.phone=arg
# for i in range(10):
# t=threading.Thread(target=func,args=(i,))
# t.start()
# print(INFO)
# 得到的结果
# INFO={
# 1111:{
# 'phone':0,
# 'mi':10
# },
# 2222:{
# 'phone':0,
# 'mi':10
# },
# 3333:{
# 'phone':0,
# 'mi':10
# }
# }
#7.线程池(用于控制现成的数量,因为不是越多越好,效率随着)
# from concurrent.futures import ThreadPoolExecutor
# import time
# def task(a1,a2):
# time.sleep(1)
# print(a1+a2)
# pool=ThreadPoolExecutor(5) #最多只有五个线程在工作
#
# for i in range(40):
# # 去线程池中申请一个线程,让线程执行task函数
# pool.submit(task,i,i+1)
#8.生产者消费者模型
# import queue
# # q=queue.Queue() #线程安全
# # q.put(1)
# # q.put(2)
# # q.put(3)
# # q.put(4)
# # print(q.get()) #1
# 生产者模型解决了一直等待的问题
# import time
# import threading
# import queue
# q=queue.Queue() #线程安全
# def producer(id):
# '''
# 生产者
# :return:
# '''
# while 1:
# time.sleep(1)
# q.put('包子')
# print('厨师%s 生产了一个包子' % id)
# for i in range(1,3):
# t=threading.Thread(target=producer,args=(i,))
# t.start()
# def consumer(id):
# '''
# 生产者
# :return:
# '''
# while 1:
# time.sleep(2)
# q.get()
# print('顾客 %s 吃了一个包子' % id)
#
#
# for i in range(1,4):
# t1=threading.Thread(target=consumer,args=(i,))
# t1.start()
#