Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对于python客户端来说,这是一个高效的TCP/IP套接字循环吗?_Python_Sockets_Tcp_Multiprocessing - Fatal编程技术网

对于python客户端来说,这是一个高效的TCP/IP套接字循环吗?

对于python客户端来说,这是一个高效的TCP/IP套接字循环吗?,python,sockets,tcp,multiprocessing,Python,Sockets,Tcp,Multiprocessing,我正在连接一台服务器,该服务器将向我发送需要按行处理的流式数据。所以我必须解析出每一行,然后处理每一行。下面的代码似乎工作得很好,但我想知道是否有任何标准的设计模式来完成这类工作。还是这条路要走 队列是否会带来严重的开销?我需要它尽可能的快速和高效,这也是我像twisted一样远离库的原因 import socket, multiprocessing def receive_proc(s, q): data = '' while True: data += s.

我正在连接一台服务器,该服务器将向我发送需要按行处理的流式数据。所以我必须解析出每一行,然后处理每一行。下面的代码似乎工作得很好,但我想知道是否有任何标准的设计模式来完成这类工作。还是这条路要走

队列是否会带来严重的开销?我需要它尽可能的快速和高效,这也是我像twisted一样远离库的原因

import socket, multiprocessing

def receive_proc(s, q):
    data = ''
    while True:
        data += s.recv(4096)
        if '\n' in data:
            lines = data.split('\n')[:-1]
            for line in lines:
                if len(line) > 0:
                    q.put(line)
                    data = data.replace(line+'\n', '', 1)

q = multiprocessing.Queue()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 1234))

p = multiprocessing.Process(target=receive_proc, args=(s,q))
p.start()

while True:
    line = q.get()

    # do your processing here

当然,想要远离twisted这样的东西是有正当理由的,但我不认为效率在其中——我怀疑它们更有可能以正确的方式得到优化。性能是一个棘手的问题,通常瓶颈并不是你所想的,这就是为什么你需要在适当优化之前对其进行分析。例如,框架可能已经努力将更多的代码推出到C扩展中,这肯定会提高性能。如果性能是你的主要动力,那么第三方的东西可能是更安全的选择。此外,使用其他人针对各种不同的用例和环境测试和调整过的代码也有很大的争议——如果你最终重新发明了太多的轮子,那么总有可能缺少一些轮辐

但是,您需要做的事情似乎非常简单,因此安装和学习框架的开销,以及向代码中添加另一个运行时依赖项的开销可能是不合理的。此外,如果您主要是IO绑定的,那么在处理过程中消耗一点额外的CPU也不会有多大区别。在过去,我当然会避免像twisted这样的事情,因为我知道自己写会更快(就我的时间而言),而且性能会“足够好”。我总是发现twisted的回调系统使调试变得有点棘手——例如,访问错误消息可能有点令人担忧。这绝非不可能,许多人都非常成功地使用了它,但就我个人而言,我发现它太“精巧”了,无法用于简单的任务

我认为,在这种情况下,您将接收和处理拆分为自己的进程的想法可能是一种错误的经济做法——从套接字接收数据的速度非常快,如果您使用纯Python进行大量处理,这可能是主要的性能因素。但是,如果不知道您在做什么处理,我就不能确定。如果这将是耗时和/或CPU密集型的,并且您可以独立于前几行处理每一行,那么这可能是合理的,但您可能希望将处理工作分配给一整套工作进程。基于您现有的代码,这是非常容易的-只需将主进程作为接收器而不是“从进程”,并创建一个共享
队列的工作者池
。每个工人通过一个循环选择下一个项目并产生结果。不管每次花费多长时间,只要下一个项目可用,他们就会得到它(而
Queue
将为您处理)

但是,如果您的处理循环主要也是IO绑定的(例如,写入文件),那么您可能会发现单个进程实际上比将所有内容都推入管道的开销要好。这取决于许多因素,包括您的CPU体系结构(一些系统使CPU核心之间的传输比其他系统更昂贵),但最终您不想使用多个进程,除非您非常确信这将给您带来性能上的胜利

无论如何,如果循环是IO绑定的,您可能会发现使用非阻塞IO的单个进程是一个不错的选择。您可以自己使用Python的模块来完成这项工作,或者使用类似或的库,您可能会发现它更干净

抛开不相关因素不谈-您从缓冲区中剥离起始数据的方法非常低效-您不需要使用
replace()
您只需使用现有的
split()
,如下所示:

while True:
    data += s.recv(4096)
    if '\n' in data:
        lines = data.split('\n')
        for line in lines[:-1]:
            if len(line) > 0:
                q.put(line)
        data = lines[-1]

当然,想要远离twisted这样的东西是有正当理由的,但我不认为效率在其中——我怀疑它们更有可能以正确的方式得到优化。性能是一个棘手的问题,通常瓶颈并不是你所想的,这就是为什么你需要在适当优化之前对其进行分析。例如,框架可能已经努力将更多的代码推出到C扩展中,这肯定会提高性能。如果性能是你的主要动力,那么第三方的东西可能是更安全的选择。此外,使用其他人针对各种不同的用例和环境测试和调整过的代码也有很大的争议——如果你最终重新发明了太多的轮子,那么总有可能缺少一些轮辐

但是,您需要做的事情似乎非常简单,因此安装和学习框架的开销,以及向代码中添加另一个运行时依赖项的开销可能是不合理的。此外,如果您主要是IO绑定的,那么在处理过程中消耗一点额外的CPU也不会有多大区别。在过去,我当然会避免像twisted这样的事情,因为我知道自己写会更快(就我的时间而言),而且性能会“足够好”。我总是发现twisted的回调系统使调试变得有点棘手——例如,访问错误消息可能有点令人担忧。这绝非不可能,许多人都非常成功地使用了它,但就我个人而言,我发现它太“精巧”了,无法用于简单的任务

我认为,在这种情况下,您将接收和处理拆分为自己的进程的想法可能是一种错误的经济做法——从套接字接收数据的速度非常快,如果您使用纯Python进行大量的处理,那就太糟糕了