문제
말하자 저는 읽고 싶은 라인에서는 소켓을 사용하여 표준 socket
모듈:
def read_line(s):
ret = ''
while True:
c = s.recv(1)
if c == '\n' or c == '':
break
else:
ret += c
return ret
정확히 무슨 일에 s.recv(1)
?그것은 문제는 시스템 호출은 각 시간입니까?나를 버퍼링,어쨌든:
에 대한 최고의와 일치 하드웨어와 네트워크 현실의 값 bufsize 해 상대적으로 작은 전력의 2,예를 들어,4096.
http://docs.python.org/library/socket.html#socket.socket.recv
하지만 그것은 보이지 않는 쓰기 쉽 효율적이고 스레드에 안전한 버퍼링이다.무엇을 사용하는 경우 file.readline()
?
# does this work well, is it efficiently buffered?
s.makefile().readline()
해결책
그만큼 recv()
전화는 C 라이브러리 기능을 호출하여 직접 처리됩니다.
소켓에 데이터가있을 때까지 기다릴 것입니다. 실제로 그것은 단지 그것을 허용 할 것입니다 recv()
시스템 호출 블록.
file.readline()
효율적인 버퍼 구현입니다. 파일을 읽는 유일한 사람이라고 가정하기 때문에 ThreadSafe가 아닙니다. (예를 들어, 다가오는 입력을 버퍼링하여.)
파일 객체를 사용하는 경우 매번 read()
긍정적 인 주장으로 호출되며, 기본 코드는 recv()
이미 버퍼링되지 않는 한 요청 된 데이터 금액 만.
다음과 같은 경우 버퍼링됩니다.
당신은 전체 버퍼를 읽는 readline ()이라고 불렀습니다.
라인의 끝은 버퍼의 끝이기 전에
따라서 버퍼에 데이터를 남겨 둡니다. 그렇지 않으면 버퍼는 일반적으로 과도하게 채워지지 않습니다.
질문의 목표는 명확하지 않습니다. 읽기 전에 데이터를 사용할 수 있는지 확인 해야하는 경우 select()
또는 소켓을 비 블로킹 모드로 설정하십시오 s.setblocking(False)
. 그런 다음 대기 데이터가없는 경우 읽기가 차단되지 않고 빈 반환됩니다.
여러 스레드가있는 파일 또는 소켓 하나를 읽고 있습니까? 소켓을 읽고 수신 된 품목을 다른 스레드로 처리하기 위해 수신 품목을 큐에 공급하는 데 단일 작업자를 두었습니다.
컨설팅을 제안하십시오 파이썬 소켓 모듈 소스 그리고 C 시스템을 호출하는 소스.
다른 팁
당신이 우려하는 성능 및 제어 소켓전 (당신은 그것을 통과하는 라이브러리로 예를 들어)다음을 시도를 구현하 당신의 자신의 버퍼링 파이썬--Python 문자열입니다.찾아서 문자열입니다.분할하고 있습니다 다 놀랍게도 빠릅니다.
def linesplit(socket):
buffer = socket.recv(4096)
buffering = True
while buffering:
if "\n" in buffer:
(line, buffer) = buffer.split("\n", 1)
yield line + "\n"
else:
more = socket.recv(4096)
if not more:
buffering = False
else:
buffer += more
if buffer:
yield buffer
것으로 예상되는 경우 페이로드의 구성인 지 않은 너무 거대한,실행해야 하는 빠르 과 피를 통해 너무 많은 층의 기능 통화하고 있습니다.나는 흥미를 알기에 비교하는 방법 파일입니다.readline()또는 소켓을 사용하여.recv(1).
def buffered_readlines(pull_next_chunk, buf_size=4096):
"""
pull_next_chunk is callable that should accept one positional argument max_len,
i.e. socket.recv or file().read and returns string of up to max_len long or
empty one when nothing left to read.
>>> for line in buffered_readlines(socket.recv, 16384):
... print line
...
>>> # the following code won't read whole file into memory
... # before splitting it into lines like .readlines method
... # of file does. Also it won't block until FIFO-file is closed
...
>>> for line in buffered_readlines(open('huge_file').read):
... # process it on per-line basis
...
>>>
"""
chunks = []
while True:
chunk = pull_next_chunk(buf_size)
if not chunk:
if chunks:
yield ''.join(chunks)
break
if not '\n' in chunk:
chunks.append(chunk)
continue
chunk = chunk.split('\n')
if chunks:
yield ''.join(chunks + [chunk[0]])
else:
yield chunk[0]
for line in chunk[1:-1]:
yield line
if chunk[-1]:
chunks = [chunk[-1]]
else:
chunks = []