国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

epoll 的使用

ormsf / 2178人閱讀

摘要:的應(yīng)用很多乃至攜程都跟它又關(guān)系所以趁著失業(yè)的無(wú)聊的事件從基礎(chǔ)學(xué)起了解下的用法在的包含了訪(fǎng)問(wèn)庫(kù)的。

#

epoll的應(yīng)用很多,nginx,tornado,乃至攜程,都跟它又關(guān)系.所以趁著失業(yè)的無(wú)聊的事件,從基礎(chǔ)學(xué)起,了解下epoll的用法

epoll 在python的api

Python包含了訪(fǎng)問(wèn)Linux epoll庫(kù)的API。這篇文章用幾個(gè)簡(jiǎn)單的例子來(lái)展示下這個(gè)API

常用api
select.epoll() #返回創(chuàng)建epoll對(duì)象
epoll.register(fd[, eventmask]) #將fd的事件注冊(cè)到epoll對(duì)象中
epoll.unregister(fd) #去除fd
epoll.poll([timeout=-1[, maxevents=-1]]) #等待事件
epoll.modify(fd, eventmask) #更改fd關(guān)注的事件

更多api文檔,可以在dash中查看

常用事件常量
EPOLLIN     可讀事件
EPOLLOUT    可寫(xiě)事件
EPOLLERR    錯(cuò)誤事件
EPOLLHUP    掛起事件
示例代碼

以下是簡(jiǎn)單的helloword 程序,運(yùn)行程序后,瀏覽器訪(fǎng)問(wèn)localhost:8080/ 輸出helloword

# coding: utf-8
import socket, select
from ipdb import set_trace
EOL1 = b"

"
EOL2 = b"

"
response  = b"HTTP/1.0 200 OK
Date: Mon, 1 Jan 1996 01:01:01 GMT
"
response += b"Content-Type: text/plain
Content-Length: 13

"
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(10240)
serversocket.setblocking(0)
serversocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

#創(chuàng)建epoll對(duì)象,epoll對(duì)象是個(gè)存儲(chǔ)"fd-事件"的容器,把關(guān)注的"fd-事件"注冊(cè)到容器中,
#接下來(lái)就可以監(jiān)聽(tīng)到fd的事件
epoll = select.epoll()

#將server的sockect注冊(cè)到epoll中,因?yàn)榇耸纠绦蚬δ苁菫g覽器顯示helloword,
#所以關(guān)注接入的客戶(hù)端fd,當(dāng)有客戶(hù)端連接時(shí),出發(fā)的一定是server sockect的EPOLLIN
epoll.register(serversocket.fileno(), select.EPOLLIN)

try:
   connections = {}; requests = {}; responses = {}
   while True:
      events = epoll.poll(10)
      # print "=="*10
      for fileno, event in events:
         #客戶(hù)端接入時(shí),注冊(cè)客戶(hù)端fd到epoll,第一步需要讀取客戶(hù)端發(fā)送到服務(wù)端的信息,所以用EPOLLIN
         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
         #讀取客戶(hù)端信息
         elif event & select.EPOLLIN:
            data=connections[fileno].recv(1024)

            requests[fileno] += data
            #判斷客戶(hù)端信息是否讀取完畢
            if EOL1 in requests[fileno] or EOL2 in requests[fileno]:
               epoll.modify(fileno, select.EPOLLOUT)
               print("-"*40 + str(fileno) + "
" + requests[fileno].decode()[:-2])
            #處理客戶(hù)端關(guān)閉請(qǐng)求時(shí)的信息,防止服務(wù)端程序出現(xiàn)close_wait
            #使用telnet測(cè)試后發(fā)現(xiàn),客戶(hù)端主動(dòng)關(guān)閉時(shí)會(huì)發(fā)送個(gè)空信息到客戶(hù)端,不處理的話(huà),會(huì)出現(xiàn)close_wait,
            #并且循環(huán)中每次都會(huì)出現(xiàn)該事件,會(huì)嚴(yán)重影響程序處理效率,因此需要把它從epoll重移除
            if data == b"":
               print "receiv client close : %s "% str(fileno)
               epoll.unregister(fileno)
               try :
                  connections[fileno].close()
               except Exception, e:
                  print " connection was allready closed....."+e
         #將此接入返回給客戶(hù)端
         elif event & select.EPOLLOUT:
            byteswritten = connections[fileno].send(responses[fileno])
            responses[fileno] = responses[fileno][byteswritten:]
            if len(responses[fileno]) == 0:
               epoll.modify(fileno, 0)
               try:
                  connections[fileno].shutdown(socket.SHUT_RDWR)
               except Exception, e:
                  print " connection was allready closed....." + e
         #服務(wù)端主動(dòng)關(guān)閉連接時(shí)的邏輯處理
         elif event & select.EPOLLHUP:
            print "close fd : %s "% str(fileno)
            epoll.unregister(fileno)
            connections[fileno].close()
            del connections[fileno]
         else :
            print "="*10
            print fileno,event
finally:
   # set_trace()
   epoll.unregister(serversocket.fileno())
   epoll.close()
   serversocket.close()
總結(jié)

這段程序大部分摘抄自http://scotdoyle.com/python-epoll-howto.html
但經(jīng)過(guò)測(cè)試發(fā)現(xiàn)他的程序有些bug.
使用telnet測(cè)試后發(fā)現(xiàn),客戶(hù)端主動(dòng)關(guān)閉時(shí)會(huì)發(fā)送個(gè)空信息到客戶(hù)端,不處理的話(huà),會(huì)出現(xiàn)close_wait.
并且循環(huán)中每次都會(huì)出現(xiàn)該事件,會(huì)嚴(yán)重影響程序處理效率,因此需要把它從epoll重移除.
原因發(fā)生tcp協(xié)議中四次握手時(shí),客戶(hù)端的關(guān)閉消息沒(méi)有被處理

理解這些bug對(duì)epoll使用很有幫助

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/37558.html

相關(guān)文章

  • Swoole 4.4:支持 CURL 協(xié)程化

    摘要:在之前的版本中,一直不支持協(xié)程化,在代碼中無(wú)法使用。由于使用了庫(kù)實(shí)現(xiàn),無(wú)法直接它的,版本使用模擬實(shí)現(xiàn)了的,并在底層替換了等函數(shù)的。跟蹤使用跟蹤發(fā)現(xiàn),所有系統(tǒng)調(diào)用均變成的異步非阻塞調(diào)用了。 在4.4之前的版本中,Swoole一直不支持CURL協(xié)程化,在代碼中無(wú)法使用curl。由于curl使用了libcurl庫(kù)實(shí)現(xiàn),無(wú)法直接hook它的socket,4.4版本使用SwooleCorouti...

    RobinTang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

ormsf

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<