信号量
from threading import Semaphore,Thread import timedef func(a,b):time.sleep(1)sem.acquire()print(a+b)sem.release()sem = Semaphore(4) for i in range(10):t = Thread(target=func,args=(i,i+5))t.start()
事件
# 事件被创建的时候,默认为False状态 # Flase状态 wait()阻塞 # True 状态 wait()非阻塞 # clear 设置状态为False # set 设置状态位True# 连接数据库 # 检测数据库的可连接情况import time import random from threading import Thread,Eventdef connect_db(e):count = 0while count<3:e.wait(0.5) # 状态为False的时候,只等待1秒就结束if e.is_set():print('连接数据库')breakelse:print('第%s次连接失败'%(count+1))count += 1else:raise TimeoutError('数据库连接超时')def check_web(e):time.sleep(random.randint(0,3))e.set()e = Event() t1 = Thread(target=connect_db,args=(e,)) t2 = Thread(target=check_web,args=(e,)) t1.start() t2.start()
条件:
条件——锁
一个条件被创建之初,默认有一个False状态
False状态,会影响wait一直处于等待状态
notify(int数据类型) 制作一串钥匙
from threading import Condition,Threaddef func(con,i):con.acquire()con.wait()print('在第%s个循环'% i)con.release()con = Condition() for i in range(10):Thread(target=func,args=(con,i)).start() while True:num = int(input('>>>'))con.acquire()con.notify(num)con.release()
定时器
from threading import Timer import time def func():print('时间同步')while True:Timer(2,func).start()time.sleep(2)
队列
# queue # 队列的特点:先进先出 # import queue # q = queue.Queue() # q.put() # q.get() # q.put_nowait() # q.get_nowait()# 栈 先进后出 # import queue # q = queue.LifoQueue() # q.put(1) # # q.put(2) # q.put(3) # print(q.get())# 优先级队列 数值越低优先级越高,优先级一样按照ASCII码排 # import queue # q = queue.PriorityQueue() # q.put((20,'a')) # q.put((10,'b')) # q.put((40,'c')) # q.put((2,'e')) # q.put((2,'d')) # print(q.get())
线程池
from concurrent.futures import ThreadPoolExecutor import time def func(n):time.sleep(2)print(n)return n*n def call_back(m):print('结果是:',m.result())tpool = ThreadPoolExecutor(max_workers=5) # 默认 不要超过cpu个数*5 for i in range(20):t = tpool.submit(func,i).add_done_callback(call_back)# tpool.map(func,range(20)) # t_lst = [] # for i in range(20): # t = tpool.submit(func,i) # t_lst.append(t) # # tpool.shutdown() #close+join # print('主线程') # for t in t_lst:print('****',t.result())# 起进程池的话和线程池一模一样,改个名字就可以了