python的select和epoll


python的select和epoll

1.select模型:

  • linux中每個套接字都是文件,都有唯一的文件描述符,這些設備的文件描述符被放在一個數組中,然后select調用的時候遍歷這個數組,如果對於的文件描述符可讀則會返回改文件描述符。當遍歷結束之后,如果仍然沒有一個可用設備文件描述符,select讓用戶進程則會睡眠,直到等待資源可用的時候在喚醒,遍歷之前那個監視的數組。每次遍歷都是以輪詢的方式依次進行判斷的。

select實現回顯服務器:


from socket import *
from select import *

s = socket(2,1)
s.setsockopt(1,2,1)
s.bind(('',8080))
s.listen(1024)

s_list = [s.fileno(),]  #fileno()獲取套接字的唯一描述符,每個套接字都是唯一不同的
s_dict = {}

while 1:
    list_readable,a,b = select(s_list,[],[]) #分別對應: 輸入,輸出,錯誤輸出
    for i in list_readable:
        if i == s.fileno():
            conn,userinfo = s.accept()
            s_list.append(conn.fileno())
            s_dict[conn.fileno()] = conn
        else:
            cs = s_dict[i]
            recv_data = cs.recv(1024)
            if len(recv_data) <= 0:
                s_dict[i].close()
                s_dict.pop(i)
                s_list.remove(i)
            else:
                cs.send(recv_data)


2.epoll模型:

  • select模型會受到文件描述符數量的限制,所以一般最多是1024個套接字,而epoll突破了此限制。
  • epoll采用的是事件通知機制,而不再是以輪詢的方式挨個詢問每個文件描述符的狀態,節省cpu時間。
  • epoll是select的進階版。一般情況下epoll效率更高

epoll實現回顯服務器:


from socket import *
from select import *

s = socket(2,1)
s.setsockopt(1,2,1)
s.bind(('',8080))
s.listen(1024)

s_dict = {}

epoll_instance = epoll()
epoll_instance.register(s.fileno(),EPOLLIN|EPOLLET)
while 1:
    epoll_list = epoll_instance.poll()
    for fd,event in epoll_list:
        if fd == s.fileno():
            cs,userinfo = s.accept()
            epoll_instance.register(cs.fileno(),EPOLLIN|EPOLLET)
            s_dict[cs.fileno()] = cs
        else:
            cs = s_dict[fd]
            recv_data = cs.recv(1024)
            print(recv_data.decode('gb2312'))
            if len(recv_data) > 0 :
                cs.send(recv_data)
            else:
                print('adsfasdf')
                epoll_instance.unregister(fd)
                cs.close()
                s_dict.pop(fd)
            
  • 注:EPOLLIN(可讀),EPOLLOUT(可寫)
  • EPOLLET: 邊緣觸發模式(只通知一次)
  • EPOLLLT:水平觸發模式(通知后沒有做處理的話還會繼續通知)


免責聲明!

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



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