在 Python 中使用 epoll[譯文]__Python

來源:互聯網
上載者:User


原文地址: http://scotdoyle.com/python-epoll-howto.html ,我這裡取精簡內容翻譯過來。

============ 本文開始 ============ 介紹

Python 從 2.6 開始支援 epoll。現在我們用 Python3 來寫基於這些 API的 epoll 範例。 阻塞的 Socket 通訊範例

import socketEOL1 = b'\n\n'EOL2 = b'\n\r\n'response  = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n'response += b'Content-Type: text/plain\r\nContent-Length: 13\r\n\r\n'response += b'Hello, world!'serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)serversocket.bind(('0.0.0.0', 8080))serversocket.listen(1)try:   while True:      connectiontoclient, address = serversocket.accept()      request = b''      while EOL1 not in request and EOL2 not in request:          request += connectiontoclient.recv(1024)      print('-'*40 + '\n' + request.decode()[:-2])      connectiontoclient.send(response)      connectiontoclient.close()finally:   serversocket.close()

這個範例中的代碼在 accept() 、 recv() 和 send() 時候會發生阻塞,導致其他串連無法完成。

通常情況下,在我們使用阻塞模型時候,會專門建立一個主線程來進行監聽,將建立成功的串連交給其他線程操作,然後繼續在主線程上面監聽。這樣一來,就不會受單次請求阻塞的限制。

C10K 問題描述了其他處理高並發方法,比如非同步 Socket,通過監聽事件來觸發預設的響應。非同步 Socket 可以是單線程,也可以是多線程。

Python 的 API 中包含了 select / poll / epoll,具體的可用性依賴於作業系統。他們的效率是 epoll > poll > select,從這個 效能測試文章 就可以看出來。 epoll 非同步編程範例

epoll 的流程是這樣的: 建立 epoll 執行個體 告訴 epoll 去監聽哪幾種類型事件 向 epoll 查詢最近已監聽事件的變化 根據不同的類型做不同的處理 讓 epoll 修改監聽列表 重複 3-5 直到結束 消滅 epoll 執行個體

範例代碼:

import socket, selectEOL1 = b'\n\n'EOL2 = b'\n\r\n'response  = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n'response += b'Content-Type: text/plain\r\nContent-Length: 13\r\n\r\n'response += b'Hello, world!'serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)serversocket.bind(('0.0.0.0', 8080))serversocket.listen(1)serversocket.setblocking(0)epoll = select.epoll()epoll.register(serversocket.fileno(), select.EPOLLIN)try:   connections = {}; requests = {}; responses = {}   while True:      events = epoll.poll(1)      for fileno, event in events:         if fileno == serversocket.fileno():            connection, address = serversocket.accept()            connection.setblocking(0)            epoll.register(connection.fileno(), select.EPOLLIN)            connections[connection.fileno()] = connection            requests[connection.fileno()] = b''            responses[connection.fileno()] = response         elif event & select.EPOLLIN:            requests[fileno] += connections[fileno].recv(1024)            if EOL1 in requests[fileno] or EOL2 in requests[fileno]:               epoll.modify(fileno, select.EPOLLOUT)               print('-'*40 + '\n' + requests[fileno].decode()[:-2])         elif event & select.EPOLLOUT:            byteswritten = connections[fileno].send(responses[fileno])            responses[fileno] = responses[fileno][byteswritten:]            if len(responses[fileno]) == 0:               epoll.modify(fileno, 0)               connections[fileno].shutdown(socket.SHUT_RDWR)         elif event & select.EPOLLHUP:            epoll.unregister(fileno)            connections[fileno].close()            del connections[fileno]finally:   epoll.unregister(serversocket.fileno())   epoll.close()   serversocket.close()

最關鍵的幾行如下: 16:註冊感興趣的事件 23:如果發現是監聽 socket,則建立串連 30:讀事件處理 33:讀事件完成後,修改 epoll 對應的狀態到寫事件 35:寫事件 41:釋放對應的串連

Epoll 分邊緣觸發(edge-triggered)和水平觸發(level-triggered)兩種,前者只被核心觸發一次通知(除非狀態被改變為未就緒),後者在觸發後如果不做操作,以後仍然會收到核心的觸發通知。 更多最佳化 串連等待池大小

我們之前的代碼直接使用 listen() 建立串連,可以通過設定一個隊列大小,在隊列滿了時候,就不再接受新的串連,從而保證已經接受的串連順利完成。 TCP 選項

使用 [TCP_CORK][] 功能,可以將小資料包封裝成大包傳輸,提高效率。

[TCP_NODELAY][] 則作用相反,將大包分成小包發送出去。比較適合即時應用比如 SSH。

(譯者:Linux下高效能網路編程中的幾個TCP/IP選項介紹這幾個 HTTP,寫的不錯。

範例中的源碼在 source code 下載。 原文連結: http://blog.log4d.com/2013/01/python-epoll/
3a1ff193cee606bd1e2ea554a16353ee

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.