epoll技術-多路複用進行抗併發
阿新 • • 發佈:2019-01-14
epoll技術-多路複用進行抗併發
首先必須清楚,這個程式碼在windows下面無法執行,因為windows系統不支援,要搞就是在linux中擼
epoll技術核心的與socket的根本區別就是解決了輪詢問題
epoll技術不是用的輪詢,而是反向的,挨個去詢問監控區裡面的內容有沒有變化太低端了,牛皮的都是吼一聲,監控區裡面的誰狀態改變了自己報上名來
核心就乾的這個事情,如果監控區裡面的物件發生了狀態的變化則會自動向系統發出一個訊號,系統接收到訊號後將這些狀態變化的物件以列表的形式進行返回
之後的程式碼就跟上一篇說的邏輯一樣
from socket import *
import select
def main():
# 建立物件
server = socket(AF_INET, SOCK_STREAM)
# 配置斷開釋放埠
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 掛起伺服器
server.bind(('', 8888))
# 設定成監聽模式
server.listen()
# 建立epoll物件
epoll = select.epoll()
# 使用epoll物件進行註冊,註冊的目的就是讓核心對註冊的內容進行監聽
epoll.register(server.fileno(),select.EPOLLIN) # 其儲存的是檔案識別符號
# 建立字典用於儲存客戶端連線上server之後建立的物件
obj = {}
# 建立字典用於客戶端連線上server之後儲存客戶端資訊
client_info = {}
while True:
# 核心進行阻塞監聽,並將發生變動的檔案識別符號返回出來
epoll_list = epoll.poll()
# 遍歷發生變動檔案識別符號
for fb, events in epoll_list: # 這個地方很坑,events雖然沒有什麼亂用,但是還是要寫,因為epoll_list返回的是一個元組兩個元素
# 進行判斷,如果是使用者的連線動作,則變動的檔案識別符號一定是sever
if fb == server.fileno():
# 表示使用者連線,需要建立新的物件進行
new_server, link_client = server.accept()
print(f'使用者{link_client}已經連線成功')
# 將新連線的物件註冊到epoll中
epoll.register(new_server.fileno(), select.EPOLLIN)
# 將物件放入到對應的準備好的字典中
obj[new_server.fileno()] = new_server
# 將使用者資訊放到對應的字典中
client_info[new_server.fileno()] = link_client
else:
# 如果不是連線請求,則一定是已經連線的使用者傳送資料請求,這裡就接收資料
# 讀取資料
data = obj[fb].recv(1024)
print(f'收到來自使用者{client_info[fb]}的資料:{data}')
# 收據接收完成周進行關閉連線
obj[fb].close()
# 需要將字典中的資料清除
del obj[fb]
del client_info[fb]
# 清除epoll中的註冊資訊
epoll.unregister(fb)
if __name__ == '__main__':
main()
需要注意的是:
epoll技術不僅對連線數沒有限制,而且還採用了自發的監控模式,這就非常好的提升了整體抗併發的效能
話雖然如此,但是在併發這種問題上,肯定是要要求快速處理的,那麼實際上python本身就不是一個以速度為有優勢的語言,要想搞速度顯然是使用c,所以對於解決併發問題,python幾乎是沒有用到