day35:线程队列&进程池和线程池&回调函数&协程
目录1.线程队列 2.进程池和线程池 3.回调函数 4.协程:线程的具体实现 5.利用协程爬取数据 附:并发编程思维导图 线程队列1.线程队列的基本方法put 存 get 取 put_nowait 存,超出了队列长度,报错 get_nowait 取,没数据的时候,直接报错 [linux windows] 线程中 put_nowait/get_nowait 都支持(区别于进程队列) 2.Queue:先进先出,后进后出# (1) Queue """先进先出,后进后出""" q = Queue() q.put(1) q.put(2) print(q.get()) (q.get()) print(q.get()) 取不出来,阻塞 print(q.get_nowait()) 没有数据时,报错 指定队列长度 q2 = Queue(3) q2.put(100) q2.put(101) q2.put(102) q2.put(103) 存放的数据超出了队列长度,阻塞 q2.put_nowait(104)(2)LifoQueue 先进后出,后进先出(栈的特点) from queue import LifoQueue lq = LifoQueue(3) lq.put(11) lq.put(22) lq.put(33) lq.put_nowait(44) error print(lq.get()) 33 22 11 阻塞 4.PriorityQueue:按照优先级顺序进行排序(3)PriorityQueue 按照优先级顺序进行排序(默认从小到大) PriorityQueue pq = PriorityQueue() 1.可以存放数字--->按照数字大小排序 pq.put(80) pq.put(81) pq.put(18) 2.可以存放字符串 (按照ascii编码进行排序,依次返回) pq.put("wangwen") pq.put(wangzhihegelong 3.可以存放容器--->按照容器的元素排序,从第一个元素开始 pq.put( (18,) ) pq.put( (18,1)">maohonglei) ) pq.put( (18,1)">wangawei) ) 4.是否可以将不同类型的数据都放到一个队列中的呢? 不可以! # error pq.put(1) pq.put("abc") """ (pq.get()) print(pq.get()) 进程池和线程池1.ProcessPoolExecutor:进程池的基本使用from concurrent.futures ProcessPoolExecutor def func(i): print(任务执行中 ... start,os.getpid()) time.sleep(3) 任务执行结束 ... end return i if __name__ == __main__: lst = [] (1) 创建进程池对象 参数: 默认获取的是最大cpu逻辑核心数 8 p = ProcessPoolExecutor(8) (2) 异步提交任务 默认如果一个进程短时间内可以完成更多的任务,进程池就不会使用更多的进程来完成,以节省资源""" for i in range(10): res = p.submit(func,i) lst.append(res) (3) 获取当前进程任务中的返回值(result在获取任务的返回值时,有阻塞) in lst: (i.result()) (4) 等待所有子进程执行结束之后,在继续执行主进程内容(shutdown) p.shutdown() <=> join <=======>print(os.getpid()) 1.创建进程池对象 2.异步提交任务 ?3.获取当前进程任务中的返回值 ?4.shutdown:等待所有子进程执行结束之后,在继续执行主进程内容 2.ThreadPoolExecutor:线程池的基本使用ThreadPoolExecutor from threading current_thread as cthread thread ... startthread ... end cthread().ident [] setvar = set() (1) 创建线程池对象 参数: 默认并发的线程数 是 os.cpu_count() * 5 = 40 tp = ThreadPoolExecutor() 默认如果一个线程短时间内可以完成更多的任务,线程池就不会使用更多的线程来完成,1)">in range(100): res = tp.submit(func,10) lst.append(res) (3) 获取返回值 lst: setvar.add(i.result()) (4) 等待所有子线程执行结束之后,在执行主线程 tp.shutdown() 主线程执行结束 .... print(setvar,len(setvar)) 创建线程池时注意: 回调函数1.进程池的回调函数: 由主进程执行调用完成的func1(i): process start ... process end ... return *" * i call_back1(obj): <===回调函数callback进程号===>(obj.result()) : p = ProcessPoolExecutor() in range(1,11 p.submit(func1,i) print(res.result()) res.add_done_callback(call_back1) self.func(func2) p.shutdown() 主进程执行结束 ... ",os.getpid()) 回调函数执行流程 2.线程池的回调函数 : 由当前子线程调用完成的func2(i): thread start ... thread end ... call_back2(obj): <===回调函数callback线程号===>(obj.result()) : tp = ThreadPoolExecutor(5 tp.submit(func2,i) res.add_done_callback(call_back2) tp.shutdown() 主线程执行结束 ... 线程池的回调函数是由当前子线程调用完成的 |