Python I/O多路復用 阻塞、非阻塞、同步、異步


一、python 之 IO多路復用

  • 1.1 多路復用概念:

監聽多個描述符(文件描述符(windows下暫不支持)、網絡描述符)的狀態,如果描述符狀態改變 則會被內核修改標志位,進而被進程獲取進而進行讀寫操作

  • 1.2 多路復用兩種觸發方式:

水平觸發(Level Triggered):

將就緒的文件描述符告訴進程后,如果進程沒有對其進行IO操作,那么下次調用select()和poll()的時候將再次報告這些文件描述符,所以它們一般不會丟失就緒的消息,但是會增加消耗

邊緣觸發(Edge Triggered):

只告訴進程哪些文件描述符剛剛變為就緒狀態,它只說一遍,如果我們沒有采取行動,那么它將不會再次告知,理論上邊緣觸發的性能要更高一些,但是代碼實現相當復雜。

  • 1.3 阻塞/非阻塞 模式:

阻塞:

如果阻塞模式則等待數據

非阻塞:

如果非阻塞模式有數據返回數據、無數據直接返回報錯

  • 1.4 I/O模型:

同步I/O:

一問一答 等待數據(阻塞模式)或 不管有沒有數據都返回(非阻塞模式)

異步I/O:

用戶進程問完之后干別的處理結果出來之后告知用戶進程

  • 1.5 selec/poll/epoll

相同點和不同點圖解

clip_image002[11]

select/poll/epoll詳解

Python IO復用之select

格式:

rList,wList,eList = select.select(argv1,argv2,argv3,timeout)

 

參數:

argv1 標准輸入

argv2 如果監聽序列中句柄發生變化 則將變化句柄返回至wList

argv3 如果監聽序列中句柄有錯誤時 則將錯誤句柄返回到eList

timeout 設置阻塞時間,如果為2那么將阻塞2s,如果不設置則默認一直阻塞

實例:

select 服務端:

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import select,socket
sock1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_address = ('127.0.0.1',8081)
sock1.bind(server_address)
sock1.listen(5)
#制定select監聽列表sock1為select監聽的一個元素
input_list = [sock1,]
while True:
#當input_list中的句柄發生變化時,select會將發生變化的句柄添加到rList列表中
rList,wList,eList = select.select(input_list,[],[])
#打印出當前rList中的元素 你會發現沒有客戶端連接的時候rList是空的 當有連接過來時rList就會發生改變
print rList
#循環發生變化的句柄列表
for r in rList:
#如果句柄是sock1 進入監聽狀態 並將客戶端socket對象(conn)添加到input_list
if r == sock1:
conn,address = r.accept()
print address
input_list.append(conn)
#如果不是sock1 那么就是上面添加的客戶端socket對象(conn)
else:
data = r.recv(1024)
r.send(data)

 

 

socket 客戶端

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import socket
socket_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_address = ('127.0.0.1',8081)
socket_client.connect(server_address)
while True:
string = raw_input('please input:')
socket_client.send(string)
server_data = socket_client.recv(1024)
print server_data
socket_client.close()

 

(注:執行多個客戶端你會發現一個很有趣的現象)

Ø 1.2 Python IO復用之poll

觸發方式:

水平觸發

只適用於Unix/Linux操作系統

Ø 1.3 Python IO復用之epoll

觸發方式:

邊緣觸發

只適用於Unix/Linux操作系統


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM