1.socket服務端實現併發
現在回來想網路程式設計服務端需要滿足哪幾點需求
2.程序池執行緒池介紹
執行緒不可能無限制的開下去,總要消耗和占用資源
程序池執行緒池概念:硬體有極限,為了減輕硬體壓力,所以有了池的概念
注意協程這個概念完全是程式設計師自己想出來的東西,它對於作業系統來說根本不存在。作業系統只知道程序和執行緒。並且需要注意的是並不是單個執行緒下實現切換+儲存狀態就能提公升效率,因為你可能是沒有遇到io也切,那反而會降低效率
再回過頭來想上面的socket服務端實現併發的例子,單個執行緒服務端在建立連線的時候無法去幹通訊的活,在幹通訊的時候也無法去幹連線的活。這兩者肯定都會有io,如果能夠實現通訊io了我就去幹建連線,建連線io了我就去幹通訊,那其實我們就可以實現單執行緒下實現併發
將單個執行緒的效率提公升到最高,多程序下開多執行緒,多執行緒下用協程》 實現高併發!!!
三者都是實現併發的手段
#view codeyield能夠實現儲存上次執行狀態,但是無法識別遇到io才切換
#序列執行
import
time
deffunc1():
for i in range(10000000):
i+1deffunc2():
for i in range(10000000):
i+1start =time.time()
func1()
func2()
stop =time.time()
print(stop -start)
#基於yield併發執行
import
time
deffunc1():
while
true:
10000000+1
yield
deffunc2():
g=func1()
for i in range(10000000):
#time.sleep(100) # 模擬io,yield並不會捕捉到並自動切換
i+1next(g)
start=time.time()
func2()
stop=time.time()
print(stop-start)
yield並不能幫我們自動捕獲到io行為才切換,那什麼模組可以呢?
3.gevent模組
乙個spawn就是乙個幫你管理任務的物件
gevent模組不能識別它本身以外的所有的io行為,但是它內部封裝了乙個模組,能夠幫助我們識別所有的io行為
from gevent import monkey;monkey.patch_all() #view code檢測所有的io行為
from gevent import spawn,joinall #
joinall列表裡面放多個物件,實現join效果
import
time
defplay(name):
print('
%s play 1
' %name)
time.sleep(5)
print('
%s play 2
' %name)
defeat(name):
print('
%s eat 1
' %name)
time.sleep(3)
print('
%s eat 2
' %name)
start=time.time()
g1=spawn(play,'
劉清正'
)g2=spawn(eat,'
劉清正')#
g1.join()
#g2.join()
joinall([g1,g2])
print('
主',time.time()-start) #
單執行緒下實現併發,提公升效率
4.協程實現服務端客戶端通訊
鏈結和通訊都是io密集型操作,我們只需要在這兩者之間來回切換其實就能實現併發的效果
服務端監測鏈結和通訊任務,客戶端起多執行緒同時鏈結服務端
#view code服務端from gevent import
monkey;monkey.patch_all()
from socket import *
from gevent import
spawn
defcommunicate(conn):
while
true:
try:
data = conn.recv(1024)
if len(data) == 0: break
conn.send(data.upper())
except
connectionreseterror:
break
conn.close()
def server(ip, port, backlog=5):
server =socket(af_inet, sock_stream)
server.bind((ip, port))
server.listen(backlog)
while true: #
鏈結迴圈
conn, client_addr =server.accept()
(client_addr)
#通訊spawn(comunicate,conn)
if__name__ == '
__main__':
g1=spawn(server,'
127.0.0.1
',8080)
g1.join()
#客戶端
from threading import
thread, current_thread
from socket import *
defclient():
client =socket(af_inet, sock_stream)
client.connect((
'127.0.0.1
', 8080))
n =0
while
true:
msg = '
%s say hello %s
' %(current_thread().name, n)
n += 1client.send(msg.encode(
'utf-8'))
data = client.recv(1024)
print(data.decode('
utf-8'))
if__name__ == '
__main__':
for i in range(500):
t = thread(target=client)
t.start()
#原本服務端需要開啟500個執行緒才能跟500個客戶端通訊,現在只需要乙個執行緒就可以扛住500客戶端
#程序下面開多個執行緒,執行緒下面再開多個協程,最大化提公升軟體執行效率
程序池和執行緒池 協程 TCP單執行緒實現併發
一 程序池和執行緒池 當被操作物件數目不大時,我們可以手動建立幾個程序和執行緒,十幾個幾十個還好,但是如果有上百個上千個。手動操作麻煩而且電腦硬體跟不上,可以會崩潰,此時程序池 執行緒池的功效就能發揮了。我們可以通過維護乙個程序池 執行緒池來控制程序數目和執行緒數目。在保證計算機硬體安全的情況下最大...
併發程式設計 協程 池,io模型
一 執行緒池 程序池 開程序 開執行緒都需要消耗資源,只不過兩者比較的情況執行緒消耗的資源比較少 在計算機能夠承受範圍之內最大限度的利用計算機 什麼是池?在保證計算機硬體安全的情況下最大限度的利用計算機 池其實是降低了程式的執行效率,但是保證了計算機硬體的安全 硬體的發展跟不上軟體的速度 呼叫fro...
併發程式設計 執行緒池與程序池
以時間換空間 程序池 乙個容器,這個容器限制住你開啟程序的數量,預設是os.cpu count 我的電腦是8核,所以能開啟8個,第一次肯定只能並行的處理8個任務,只要有任務完成,程序馬上就會接下乙個任務。實現 from concurrent.futures import processpoolexe...