1.线程锁
1.锁Lock(只能锁一次)
1 import threading 2 import time 3 4 v = [] 5 lock = threading.Lock() 6 7 def func(arg): 8 lock.acquire() 9 v.append(arg) 10 time.sleep(1) 11 m = v[-1] 12 print(arg,m) 13 lock.release() 14 15 for i in range(10): 16 t = threading.Thread(target=func,args=(i,)) 17 t.start()
2.锁RLock(可以锁多次)
1 import threading 2 import time 3 4 v = [] 5 lock = threading.RLock() 6 7 def func(arg): 8 lock.acquire() 9 lock.acquire() 10 11 v.append(arg) 12 time.sleep(1) 13 m = v[-1] 14 print(arg,m) 15 16 lock.release() 17 lock.release() 18 19 20 for i in range(10): 21 t = threading.Thread(target=func,args=(i,)) 22 t.start()
3.锁semaphore(一次放n个)
1 import threading 2 import time 3 4 lock = threading.BoundedSemaphore(3)#一次放三个 5 6 def func(arg): 7 lock.acquire() 8 9 print(arg) 10 time.sleep(2) 11 12 lock.release() 13 14 for i in range(20): 15 t = threading.Thread(target=func,args=(i,)) 16 t.start()
4.锁Condition(一次放指定个数)
1 import time 2 import threading 3 4 lock = threading.Condition() 5 6 #方式一 7 8 def func(arg): 9 print("线程进来了") 10 lock.acquire() 11 lock.wait()#加锁 12 13 print(arg) 14 time.sleep(1) 15 16 lock.release() 17 18 for i in range(10): 19 t = threading.Thread(target=func,args=(i,)) 20 t.start() 21 22 while True: 23 num = int(input(">>>")) 24 lock.acquire() 25 lock.notify(num) 26 lock.release() 27 28 29 #方式二 30 31 def func(): 32 print("来执行函数了") 33 input(">>>") 34 ct = threading.current_thread()#获取当前线程 35 ct.getName() 36 return True 37 38 def func1(arg): 39 print("线程进来了") 40 lock.wait_for(func) 41 print(arg) 42 time.sleep(1) 43 44 for i in range(10): 45 t = threading.Thread(target=func1,args=(i,)) 46 t.start()
5.锁Event(一次放所有)
1 import time 2 import threading 3 4 lock = threading.Event() 5 6 def func(arg): 7 print("线程来了") 8 lock.wait()#加锁 9 print(arg) 10 11 for i in range(10): 12 t = threading.Thread(target=func,args=(i,)) 13 t.start() 14 15 input(">>>") 16 lock.set()#释放锁 17 18 lock.clear()#再次加锁 19 20 for i in range(10): 21 t = threading(target=func,args=(i,)) 22 t.start() 23 24 input(">>>") 25 lock.set()
2.threadinglocal
1 import time 2 import threading 3 4 v = threading.local() 5 6 def func(arg): 7 #内部会为当前线程创建一个空间用于存储 8 v.local = arg 9 time.sleep(2) 10 print(v.local,arg)#去当前线程自己的空间取值 11 12 for i in range(10): 13 t = threading.Thread(target=func,args=(i,)) 14 t.start()
threadinglocal原理
1 import time 2 import threading 3 4 data_dict = {} 5 6 def func(arg): 7 ident = threading.get_ident() 8 data_list[ident] = arg 9 time.sleep(1) 10 print(data_dict[ident],arg) 11 12 for i in range(10): 13 t = threading.Thread(target=func,args=(i,)) 14 t.start()
1 import time 2 import threading 3 4 info = {} 5 6 class Local(object): 7 8 def __getattr__(self,item): 9 ident = threading.get_ident() 10 return info[ident][item] 11 12 def __setattr__(self,key,value): 13 ident = threading.get_ident() 14 if ident in info: 15 info[ident][key] = value 16 else: 17 info[ident] = {key:value} 18 19 obj = Local() 20 21 def func(arg): 22 obj.local = arg#调用对象的__setattr__方法 23 time.sleep(1) 24 print(obj.local,arg) 25 26 for i in range(10): 27 t = threading.Thread(target=func,args=(i,)) 28 t.start()
3.线程池
1 from concurrent.futures import ThreadPoolExecutor 2 import time 3 4 def task(a1,a2): 5 time.sleep(2) 6 print(a1,a2) 7 8 #创建一个线程池(最多五个线程) 9 pool = ThreadPoolExecutor(5) 10 11 for i in range(100): 12 #去线程池申请一个线程,让线程执行task函数 13 pool.submit(task,i,10)
4.生产者消费者模型
1 import time 2 import queue 3 import threading 4 5 q = queue.Queue()#线程安全 6 7 def producer(id): 8 while True: 9 time.sleep(1) 10 q.put("111") 11 print("生产了一个%s"% id) 12 13 for i in range(1,4): 14 t = threading.Thread(target=func,args=(i,)) 15 t.start() 16 17 def consumer(id): 18 while True: 19 time.sleep(1) 20 v1 = q.get() 21 print("消费了一个%s"% id) 22 23 for i in range(1,3): 24 t = threading.Thread(target=consumer,args=(i,)) 25 t.start()