◎知识点
进程池Pool
线程池ThreadPool
◎脚本练习
▽ 进程池Pool
""" 如果并发的任务数过多,一次性创建并启动大量的进程会给计算机带来很大的压力,那么就可以使用进程池 对创建与启动的进程进行限制和管理。 进程池中所能容纳的进程数目是固定的。 标准库模块multiprocessing中提供了一个类对象Pool,用于表示进程池。进程池中所能容纳的进程数目 可以在创建Pool实例对象时进行指定;如果不指定,默认大小是CPU的核数 """ from multiprocessing import Pool import time, random def do_sth(i): print('子进程%d启动' % i) start = time.time() time.sleep(random.random() * 10) end = time.time() print('子进程%d结束,耗时%.2f秒' % (i, end - start)) if __name__ == '__main__': print('父进程启动') # 将进程池所能容纳的最大进程数指定为3 pp = Pool(3) for i in range(1, 11): # 与方法start()类似,不同的是,创建并启动由进程池管理的子进程 pp.apply_async(do_sth, args=(i,)) # 调用方法join()之前必须先调用方法close() # 调用方法close()之后就不能让进程池再管理新的进程了 pp.close() # 父进程被阻塞 # 进程池管理的所有子进程执行完之后,父进程再从被阻塞的地方继续执行 pp.join() print('父进程结束') # 程序运行后会同时创建3个子进程,第4个子进程要等前面3个中的某一个执行结束后才会创建并启动
▽ 线程池ThreadPool
""" 如果并发的任务数过多,一次性创建并启动大量的线程会给计算机带来很大的压力,那么就可以使用线程池 对创建与启动的线程进行限制和管理。 线程池所能容纳的线程数目是固定的。 第三方库threadpool中提供了一个类对象ThreadPool,用于表示线程池。线程池中所能容纳的线程数目 可以在创建ThreadPool实例对象时进行指定;如果不指定,默认大小是CPU的核数。 """ from threadpool import ThreadPool, makeRequests import time, random def do_sth(i): print('子线程%d启动' % i) start = time.time() time.sleep(random.random() * 10) end = time.time() print('子进程%d结束,耗时%.2f秒' % (i, end - start)) if __name__ == '__main__': print('父线程启动') args_list = [] for i in range(1, 11): args_list.append(i) # 将线程池所能容纳的最大线程数指定为3 tp = ThreadPool(3) # 创建需要线程池处理的任务 requests = makeRequests(do_sth, args_list) # 将需要线程池处理的任务全部交给线程池,此后会创建并启动由线程池管理的子线程 for req in requests: tp.putRequest(req) # 父线程被阻塞 # 线程池管理的所有子线程执行完之后,父线程再从被阻塞的地方继续执行 tp.wait() print('父线程结束') # 程序运行后会同时创建3个子进程,第4个子进程要等前面3个中的某一个执行结束后才会创建并启动