当前位置:  开发笔记 > 编程语言 > 正文

我惊呆了:python和套接字+线程的奇怪问题

如何解决《我惊呆了:python和套接字+线程的奇怪问题》经验,为你挑选了1个好方法。

我有一个http-server的python脚本:http://paste2.org/p/89701,当它与ApacheBench(ab)进行基准测试时,其并发级别(-c switch)低于或等于该值我在socket.listen()中指定 - 在源代码中调用一切正常,但是只要将并发级别放在apache bench中高于socket.listen()中的值 - 调用性能就会下降,例如:

socket.listen(10)和ab -n 50 -c 10 http:// localhost / = 1200req/s

socket.listen(10)和ab -n 50 -c 11 http:// localhost / = 40req/s

socket.listen(100)和ab -n 5000 -c 100 http:// localhost / = 1000req/s

socket.listen(100)和ab -n 5000 -c 101 http:// localhost / = 32req/s

两个调用之间的代码没有任何变化,我无法弄清楚出现了什么问题 - 现在已经解决了这个问题一天了.还要注意:无论socket.listen()设置为什么或者apache中的并发(-c开关)设置为什么,相同代码的多路复用版本(我写的与线程版本进行比较)都可以工作.

我花了一天时间在IRC/python文档上,发布在comp.lang.python和我的博客上 - 我找不到任何人甚至知道可能出错的地方.帮我!



1> Florian Bösc..:

我无法确认您的结果,并且您的服务器编码为fishy.我掀起了自己的服务器,也没有这个问题.让我们将讨论转移到更简单的层面:

import thread, socket, Queue

connections = Queue.Queue()
num_threads = 10
backlog = 10

def request():
    while 1:
        conn = connections.get()
        data = ''
        while '\r\n\r\n' not in data:
            data += conn.recv(4048)
        conn.sendall('HTTP/1.1 200 OK\r\n\r\nHello World')
        conn.close()

if __name__ == '__main__':
    for _ in range(num_threads):
        thread.start_new_thread(request, ())

    acceptor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    acceptor.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    acceptor.bind(('', 1234))
    acceptor.listen(backlog)
    while 1:
        conn, addr = acceptor.accept()
        connections.put(conn)

在我的机器上:

ab -n 10000 -c 10 http://127.0.0.1:1234/ --> 8695.03 [#/sec]
ab -n 10000 -c 11 http://127.0.0.1:1234/ --> 8529.41 [#/sec]

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有