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的核數!