【发布时间】:2016-07-11 13:13:32
【问题描述】:
我的应用程序使用了多个需要一段时间才能完成的 I/O 阻塞(网络)请求。 我尝试使用多线程,但它似乎没有带来任何加速,我猜这与 Python 的 GIL 有关。
问题是所有请求都可以同时完成,并且彼此之间没有依赖关系。我该如何解决这个性能问题?
我的代码
import threading
import urllib2
import time
def send_request(url, count_str):
start_time = time.time()
urllib2.urlopen(url)
print "Request " + count_str + " took " + str(time.time() - start_time) + " started at " + str(start_time)
count = 0
for url in open('urllist.txt'):
t = threading.Thread(target=send_request, args = (url.strip(), str(count)))
t.start()
count+=1
输出是
Request 1 took 5.0150949955 started at 1458789266.78
Request 2 took 10.0112490654 started at 1458789266.79
Request 0 took 15.024559021 started at 1458789266.78
Request 3 took 20.016972065 started at 1458789266.79
urllist.txt 中的 url 指向我在本地运行的服务器,需要 5 秒才能响应。 如您所见,它们都同时“开始”,但它们是阻塞的。
【问题讨论】:
-
您可以向我们展示您的代码 :)
-
@Signal 更新了它 =) 我对 Python 中的多线程非常陌生,所以它可能有很多错误
-
q.join()应该如何返回?您的代码中没有任何内容处理Queue以调用.get(),更不用说.task_done()。你也没有从get_and_read_url返回任何东西,所以你只是在排队None。最后,我要注意:对于一般的线程,特别是Queues,Python 2 bad;如果你可以迁移到更新的 Python (3.2 or later),重写的 GIL 意味着虽然线程在 CPU 绑定任务上仍然没有任何好处,但它的运行速度并没有明显变慢,并且只消耗 GIL 开销。 -
简化代码不使用
Queue,因为这个例子不需要它+我他们是你指出的错误。我添加了一些代码来衡量每个请求的开始和结束以及输出,并使问题更清晰。
标签: python multithreading performance io gil