2011-06-22 21 views
0

我在python中编写了一个epoll包装器,它工作正常,但是最近我发现性能对于大包发送来说并不理想。我期待下入代码,发现居然有错误在Python epoll中,我可以避免errno.EWOULDBLOCK,errno.EAGAIN?

Traceback (most recent call last): 
    File "/Users/dawn/Documents/workspace/work/dev/server/sandbox/single_point/tcp_epoll.py", line 231, in send_now 
    num_bytes = self.sock.send(self.response) 
error: [Errno 35] Resource temporarily unavailable 

和以前沉默它作为文件说,所以我的发送功能做这样的LOT:

def send_now(self): 
    '''send message at once''' 
    st = time.time() 
    times = 0 
    while self.response != '': 
     try: 
      num_bytes = self.sock.send(self.response) 
      l.info('msg wrote %s %d : %r size %r',self.ip,self.port,self.response[:num_bytes],num_bytes) 
      self.response = self.response[num_bytes:]      
     except socket.error,e: 
      if e[0] in (errno.EWOULDBLOCK,errno.EAGAIN): 
       #here I printed it, but I silent it in normal days 
       #print 'would block, again %r',tb.format_exc() 
       break 
      else: 
       l.warning('%r %r socket error %r',self.ip,self.port,tb.format_exc()) 
      #must break or cause dead loop 
      break      
     except: 
      #other exceptions 
      l.warning('%r %r msg write error %r',self.ip,self.port,tb.format_exc()) 
      break  
     times += 1 
    et = time.time() 

我GOOGLE了它,并说它是由临时网络缓冲区耗尽导致的 那么如何手动和有效地检测到这个错误,而不是进入异常阶段?

因为它导致rasie /处理异常很多时间。

+0

确定我知道这会发生将套接字缓冲区已满,所以我手动增加它sock.setsockopt(socket.SOL_SOCKET,socket.SO_SNDBUF,1024 * 1024 * 10) ,并会降低例外率 – davyzhang

回答

1

使用select来查看套接字是否准备好读取或写入。

+0

或轮询,或者epoll,kevent或者kqueue。该死,但我提出了你可以做到这一点的方法。 –

+0

@Donal:他们都在'select'中。 –

+0

谢谢我实际上使用select包来做epoll,我的问题不是关于如何查看套接字是否准备好读取或写入。我其实是做了那部分。我想找到一种方法来手动检测errno.EWOULDBLOCK和errno.EAGAIN,并避免异常增加 – davyzhang