我正在尝试使用缓冲区/队列来加快python中的套接字处理速度 下面的循环缓冲区实现下面,我用于从用于IPC的localhost套接字读取最大大小
class BufferHandling:
def __init__(self, buffer_size, max_chunk_size):
self._read_index = 0
self._write_index = 0
self._buffer = bytearray(buffer_size)
self._mem_view = memoryview(self._buffer)
self._max_size = max_chunk_size
def fill_from_socket(self, _socket):
logging.debug("2 fill: write index %s , read_index %s", self._write_index , self._read_index)
if self._read_index > self._write_index:
if self._read_index - self._write_index < self._max_size:
raise RuntimeError("no place to write in buffer")
ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
self._write_index += ret
#logging.debug("1 recv_from return with %s, write index %s", ret, self._write_index)
return
# write >= read
_1st_write_size = len(self._mem_view) - self._write_index
_2nd_write_size = self._read_index
if _1st_write_size + _2nd_write_size < self._max_size:
raise RuntimeError("no place to write in buffer")
if _1st_write_size >= self._max_size:
ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
self._write_index += ret
#logging.debug("2 recv_from return with %s , write index %s", ret, self._write_index)
return
# clear some room ...
self._mem_view[:self._write_index - self._read_index] = self._mem_view[self._read_index: self._write_index]
self._write_index = self._write_index - self._read_index
self._read_index = 0
ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
self._write_index += ret
logging.debug("3 recv_from return with %s, write index %s", ret, self._write_index)
"""
# read data from cyclic buffer
# if data found , return data according to _to_read size
# else return empty string
"""
def read_from_buffer(self, _to_read):
logging.debug("1 write_index %s , read_index %s , _to_read %s", self._write_index, self._read_index, _to_read)
if self._read_index > self._write_index:
_1st_read_size = len(self._mem_view) - self._read_index
_2nd_read_size = self._write_index
if _1st_read_size >= _to_read:
data = self._buffer[self._read_index: self._read_index + _to_read]
self._read_index += _to_read
else:
data = self._buffer[self._read_index:] + self._buffer[:_to_read - _1st_read_size]
self._read_index = _to_read - _1st_read_size
else: # write >= read
_read_less = min(_to_read, self._write_index - self._read_index)
# if self._write_index - self._read_index < _to_read:
# logging.debug("2 write_index %s , read_index %s , _to_read %s", self._write_index,self._read_index,_to_read)
# #return None
logging.debug("2 write_index %s , read_index %s , _to_read %s, _read %s", self._write_index, self._read_index, _to_read, _read_less)
data = self._buffer[self._read_index: self._read_index + _read_less]
self._read_index += _read_less
return data
我这样使用它:
self.__buffer = BufferHandling(self.__LOCALHOST_SOCKET_BUFFER_LEN * 4,
self.__LOCALHOST_SOCKET_BUFFER_LEN)
data = self.__buffer.read_from_buffer(_to_read)
if len(data) < _to_read:
self._selector.select(rlist = [self.__connection], elist = [self.__connection])
self.__buffer.fill_from_socket(self.__connection)
data += self.__buffer.read_from_buffer(_to_read)
面对许多问题之后,我的问题是:还有更多Pythonic
方式可以得到同样的效果吗?
或建议使用一种更“干净”的方式来获取某种形式的io buffering