假设我想使用标准socket模块从套接字读取一行:
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)什么?每次都会发出系统调用吗?我想无论如何我应该添加一些缓冲:
s.recv(1)
为了与硬件和网络实际情况达到最佳匹配, bufsize 的值应为2的相对较小的幂,例如4096。
http://docs.python.org/library/socket.html#socket.socket.recv
但是编写高效且线程安全的缓冲似乎并不容易。如果我使用该file.readline()怎么办?
file.readline()
# does this work well, is it efficiently buffered? s.makefile().readline()
recv()通过调用C库函数直接处理该调用。
recv()
它将阻止套接字等待数据。实际上,它只会让recv()系统调用阻塞。
file.readline()是有效的缓冲实现。它不是线程安全的,因为它假定它是唯一读取文件的文件。(例如,通过缓冲即将到来的输入。)
如果使用文件对象,则每次read()使用正参数调用时,底层代码recv()仅会请求所请求的数据量,除非已对其进行了缓冲。
read()
如果满足以下条件,它将被缓冲:
您已经调用readline()来读取完整的缓冲区
行的结尾在缓冲区的结尾之前
因此将数据保留在缓冲区中。否则,缓冲区通常不会溢出。
问题的目的尚不清楚。如果需要在读取之前查看数据是否可用,可以通过select()或将套接字设置为非阻塞模式s.setblocking(False)。然后,如果没有等待的数据,读取将返回空,而不是阻塞。
select()
s.setblocking(False)
您正在读取一个具有多个线程的文件或套接字吗?我将让一个工人来读取套接字并将接收到的项目馈送到队列中,以供其他线程处理。
建议参考进行系统调用的Python Socket Module源代码和C源代码。