案例
'''模擬多個客戶端一同去訪問服務端,讓服務端支援多個客戶端訪問,從而實現併發效果
不考慮粘包問題
'''import
socket
from threading import
thread
server=socket.socket()
def communicate(conn):#
開始通訊
while
true:
try:
data=conn.recv(1024)#
阻塞print(data.decode('
utf-8'))
conn.send(data.upper())
except
connectionreseterror:
break
conn.close()
def servering(ip,port,backlog=5):#
建立連線
server.bind((ip,port))
server.listen(backlog)
while
true:
conn,addr=server.accept()#
阻塞print
(addr)
communicate(conn)
#實現併發效果 將建立連線和通訊分開,讓兩個人去做這件事,乙個人只負責一件事
if__name__ == '
__main__':
for i in range(10):
t=thread(target=servering,args=('
127.0.0.1
',8090))
t.start()
'''模擬多個客戶端一同去訪問服務端,讓服務端支援多個客戶端訪問,從而實現併發效果
不考慮粘包問題
'''import
socket
from threading import
thread
defclients(ip,port):
client = socket.socket() #
建立客戶端
client.connect((ip,port)) #
客戶端與服務端建立連線
while
true:
info=input('
>>:
').encode('
utf-8
').strip()
if len(info)==0:continue
#判斷使用者輸入是否為空
client.send(info)
data=client.recv(1024) #
接收來自服務端的回信
print(data.decode('
utf-8'))
if__name__ == '
__main__':
for i in range(10):
t=thread(target=clients,args=('
127.0.0.1
',8090))
t.start()
通過上述的兩個例子,我們認識到我們要想實現併發,並不能無限制的開程序或者執行緒,畢竟計算機硬體資源是有限的,我們如果忽略了計算機硬體的極限,那麼遲早計算機會被我們搞破壞,為了在計算機能夠承受的情況下,只能加以限制,所以就出現了程序池執行緒池的概念。
程序池就是乙個用來盛放你允許計算機一次可以開啟多少個程序的乙個容器,裡面存放的就是你規定的程序數
執行緒池是乙個用來盛放允許開啟的執行緒數,裡面存放的是你規定的執行緒數
如何實現這個呢?匯入模組current.future這個模組,裡面有兩個類,分別是執行緒池threadpoolexecutor 和程序池processpoolexecutor
from concurrent.futures importthreadpoolexecutor,processpoolexecutor
pool=threadpoolexecutor()#
裡面的引數是你規定的執行緒數,不寫的話預設是cpu*5
#pool=processpoolexecutor()#裡面的引數是你規定的程序數,不寫的話預設是cpu個數
#提交任務,是非同步提交的,他有乙個future的返回值,所以可以用future接收一下
future=pool.submit()
#提交任務完成計算之後的結果 ,如果直接在這裡輸入這個結果的話,就會強行將非同步提交變成同步,實現的效果是將併發變成序列,效率就會降低,怎麼提公升?
future.result()
本來提交任務的時候是非同步,提交完之後就可以去做別的任務了,但是一旦在這裡接收的話就會出現同步現象,如何解決,具體實現看**
#方式一:將提交的任務新增到列表,然後將池子關閉,最後一次性取出,**如下
pool=threadpoolexecutor(20)#
你規定的執行緒數
future_list=
for i in range(20):#
你要開啟的執行緒數(《=規定的執行緒數)
#非同步提交
future=pool.submit()
#列表新增就會變有序
#先關閉池子
pool.shutdown()
for future in
future_list:
#這個時候檢視結果的話就會一次性出現,不在那麼浪費時間
future.result()
但是基於上面,我們還是發現必須自己手動去處理這件事,那麼能不能想到非同步提交的點,提交之後就不管了,交給別人去做這件事呢!**函式可以做到
#方式二:將提交任務的結果交給**函式去解決
pool=threadpoolexecutor(20)
def callback('
拿到的結果是乙個future'):
return
'拿到的結果
'.result
for i in range(20):
pool.submit(
'你的任務
','任務所需要的引數
').add_done_callback('
拿到結果之後要做的個人
')
執行緒池和程序池
動態建立程序 或執行緒 是比較耗費時間的,這樣導致較慢的客戶響應。動態建立的子程序 子執行緒 通常只用來為乙個客戶服務,這將導致系統上產生大量的細微程序 或執行緒 程序間的切換將消耗大量的cpu時間。動態建立的子程序是當前程序的完整映像,當前程序必須謹慎地管理其分配的檔案描述符和堆記憶體等系統資源,...
程序池和執行緒池
系統啟動乙個新執行緒的成本是比較高的,因為它涉及與作業系統的互動。在這種情形下,使用執行緒池可以很好地提公升效能,尤其是當程式中需要建立大量生存期很短暫的執行緒時,更應該考慮使用執行緒池。執行緒池在系統啟動時即建立大量空閒的執行緒,程式只要將乙個函式提交給執行緒池,執行緒池就會啟動乙個空閒的執行緒來...
程序池和執行緒池
from concurrent.futures import threadpoolexecutor,processpoolexecutor import time,random,os def task name,n print s s is running name,os.getpid time.s...