gevent基础之阻塞与非阻塞详解

maiziedu · · 2953 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

  gevent中一个很大的改进就是将阻塞IO改为非阻塞IO,比如gevent.socket.patch就是将项目中阻塞socket变为非阻塞,因此深刻理解网络IO部分阻塞/非阻塞十分重要。   1.阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回   1)connect阻塞 ![11.png](http://studygolang.qiniudn.com/161107/0e334e573c161053fe2190dff80c7334.png)   2)接收数据阻塞 ![22.png](http://studygolang.qiniudn.com/161107/1b18eb2e967e8bb5ea08e5a25104f149.png)   2.非阻塞指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回   1)接收数据非阻塞 ![33.png](http://studygolang.qiniudn.com/161107/843641e14e87343dc44db543ea827236.png)   2)非阻塞面临的问题 ![44.png](http://studygolang.qiniudn.com/161107/28f5fd90dce2e0bae38e0502da654aba.png)   源码 1.代码示例 import logging import time import errno logging.basicConfig( level=logging.DEBUG , format='%( name ) s : % ( message ) s ' , ) if __name__ == '__main__': import socket ip = ' localhost ' port = 58562 logger = logging.getLogger ( ' client ' ) # Connect to the server logger.debug( ' creating socket ' ) s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM ) logger.debug( ' connecting to server ' ) s.setblocking(0) try: s.connect( ( ip , port ) ) except socket.error , msg : if msg[0] != errno.EINPROGRESS : logger.debug( ' error ' ) exit(1) #time.sleep(1) # Send the data message = ' Hello , world ' #len_sent = s.send ( message ) logger.debug( ' sending data: "%s"', message ) while True : try: len_sent = s.send ( message ) break except socket.error, msg : if msg[0] != errno.EAGAIN: exit(1) # Receive a response logger.debug( ' waiting for response ' ) while True: try: response = s.recv( len_sent ) break except socket.error, msg: if msg[0] != errno.EAGAIN: exit(1) logger.debug( ' response from server: "%s"', response ) # Clean up logger.debug( ' closing socket ' ) s.close() logger.debug( ' done ' ) 执行结果 ![55.png](http://studygolang.qiniudn.com/161107/d2509fbc1bde3c0113e26fc694b51ecc.png) 2.代码示例 import logging import sys import SocketServer import time logging.basicConfig(level=logging.DEBUG , format='%( name ) s : % ( message ) s ' , ) class EchoRequestHandler ( SocketServer.BaseRequestHandler ) : def __init__( self , request , client_address , server ) : self.logger = logging.getLogger ( ' EchoRequestHandler ' ) self.logger.debug( ' __init__ ' ) SocketServer.BaseRequestHandler.__init__(self, request, client_address, server) return def setup ( self ) : self.logger.debug( ' setup ' ) return SocketServer.BaseRequestHandler.setup ( self ) def handle ( self ) : self.logger.debug( ' handle ' ) # Echo the back to the client data = self.request.recv ( 1024 ) self.logger.debug( ' recv()->"%s"', data ) self.request.send( data ) return def finish ( self ) : self.logger.debug( ' finish ' ) return SocketServer.BaseRequestHandler.finish(self) class EchoServer(SocketServer.TCPServer): def __init__(self, server_address, handler_class=EchoRequestHandler): self.logger = logging.getLogger (' EchoServer ' ) Self.logger.debug ('__init__') SocketServer.TCPServer.__init__(self, server_address, handler_class) return def server_activate ( self ) : Self.logger.debug ( ' server_activate ' ) SocketServer.TCPServer.server_activate ( self ) return def serve_forever ( self ) : self.logger.debug( ' waiting for reques t ' ) Self.logger.info ( ' Handling requests , press <Ctrl-C> to quit ' ) while True : self.handle_request() return def handle_request ( self ) : Self.logger.debug ( ' handle_request ' ) return SocketServer.TCPServer.handle_request ( self ) def verify_request ( self , request , client_address ) : Self.logger.debug ( ' verify_request ( %s , %s )', request, client_address) return SocketServer.TCPServer.verify_request(self, request, client_address ) def process_request (self , request , client_address ) : Self.logger.debug ( ' process_request ( %s , %s ) ' , request , client_address ) return SocketServer.TCPServer.process_request (self , request , client_address ) def server_close ( self ) : Self.logger.debug ( ' server_close ' ) return SocketServer.TCPServer.server_close ( self ) def finish_request ( self , request , client_address ) : self.logger.debug('finish_request ( %s , %s ) ' , request , client_address ) return SocketServer.TCPServer.finish_request(self , request , client_address ) def close_request ( self , request_address ) : self.logger.debug ( ' close_request ( %s ) ' , request_address ) return SocketServer.TCPServer.close_request ( self , request_address ) if __name__ == '__main__' : import socket import threading address = ( ' localhost ' , 0 ) # let the kernel give us a port server = EchoServer ( address , EchoRequestHandler ) ip, port = server.server_address # find out what port we were given logger = logging.getLogger ( ' client ' ) logger.info( ' Server on %s : %s ' , ip , port ) server.serve_forever () 原文链接:http://www.maiziedu.com/wiki/frame/block/

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2953 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传