python 内置的线程池、进程池及其并发服务器的实现
python 内置的线程池、进程池及其并发服务器的实现
内置线程池
1 from multiprocessing.pool import ThreadPool # 导入线程池 2 import time 3 w_start = time.time() 4 def worker(): 5 time.sleep(3) 6 print('55555') 7 pool = ThreadPool(2) # 参数是线程池的数量,默认为1 8 pool.apply_async(worker) 9 pool.apply_async(worker) 10 pool.apply_async(worker) 11 pool.close() # 关闭线程池 不再提交任务 12 pool.join() # 等待线程池里面的任务执行完毕 13 print(time.time() - w_start) 14 ############### 运行结果:########## 15 55555 16 55555 17 55555 18 6.055918216705322
这里运行了6秒是因为线程池的数量为2,最多开两个线程,且这里是time.sleep(3),延迟操作,所以会两个线程
同时执行,实际上是遇到sleep阻塞之后就执行线程2了,所以两个线程执行了大概3秒!如果涉及计算密集型,
多线程是没用的,因为python默认一次智能执行一个!join之后再使用apply_async()方法就会报错,因为这个
时候线程池已经关了,而且这里没有start()方法可以调用再次开启...
内置进程池:
1 from multiprocessing import Pool # 进程池 2 import time 3 w_start = time.time() 4 def worker(kill=0): 5 time.sleep(3) 6 print('子进程正在执行{}'.format(kill)) 7 pool = Pool(4) # 参数是进程池的数量,不写默认是1个进程 8 for i in range(5): 9 pool.apply_async(worker) 10 pool.map_async(worker, [1, 2, 3]) # 把任务给进程池,加async之后,就不会等待运行结束 11 pool.close() # 关闭线程池 不再提交任务 12 pool.join() # 等待线程池里面的任务执行完毕 13 print(time.time() - w_start) 14 print('任务执行结束') 15 ###########运行结果:########### 16 子进程正在执行0 17 子进程正在执行0 18 子进程正在执行0 19 子进程正在执行0 20 子进程正在执行0 21 子进程正在执行1 22 子进程正在执行2 23 子进程正在执行3 24 6.215780258178711 25 任务执行结束
注意到这里的方法都有两种如:map()------->map_async()
前者会阻塞,加async就不会阻塞。apply()和apply_async()是同样的。
用线程池(或者进程池)实现并发服务器:
1 from multiprocessing.pool import ThreadPool 2 import socket 3 4 server = socket.socket() 5 server.bind(('', 12345)) 6 server.listen(6) 7 print('--------等待客户端连接------') 8 def worker(conn): 9 while True: 10 recv_data = conn.recv(1024) 11 if recv_data: 12 print(recv_data) 13 conn.send(recv_data) 14 else: 15 conn.close() 16 break 17 if __name__ == '__main__': 18 pool = ThreadPool(3) 19 while True: 20 conn, address = server.accept() 21 pool.apply_async(worker, args=(conn,))
由于进程池和线程池API接口设置的都一样,所以用进程池可以将ThreadPool改成Pool,导包的时候也要修改。
其他代码都差不多。ThreadPool()默认开启1个线程(线程池只有一个),这是我电脑的结果,但是老师运行调试的是
cpu的核数!
清澈的爱,只为中国