python 內置的線程池、進程池及其併發服務器的實現

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()方法就會報錯,由於這個app

時候線程池已經關了,並且這裏沒有start()方法能夠調用再次開啓...socket

內置進程池:async

 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()spa

前者會阻塞,加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的核數!

相關文章
相關標籤/搜索