dor*_*vak 9 python urllib2 multiprocessing gil
我最近尝试加速一个小工具(使用urllib2向多处理模块发送请求到(非官方)twitter-button-count-url(> 2000 urls)并解析它的结果)(并且它工人池).我在这里阅读了几个关于多线程的讨论(与标准的非线程版本相比减慢了整个过程)和多处理,但我找不到一个(可能非常简单)问题的答案:
你可以通过多处理加速网址调用,还是像网络适配器这样的瓶颈?我不知道urllib2-open-method的哪一部分可以并行化,以及它应该如何工作......
编辑:这是我想要加速的请求和当前的多处理设置:
urls=["www.foo.bar", "www.bar.foo",...]
tw_url='http://urls.api.twitter.com/1/urls/count.json?url=%s'
def getTweets(self,urls):
for i in urls:
try:
self.tw_que=urllib2.urlopen(tw_url %(i))
self.jsons=json.loads(self.tw_que.read())
self.tweets.append({'url':i,'date':today,'tweets':self.jsons['count']})
except ValueError:
print ....
continue
return self.tweets
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=4)
result = [pool.apply_async(getTweets(i,)) for i in urls]
[i.get() for i in result]
Run Code Online (Sandbox Code Playgroud)
啊,这是另一个关于GIL的讨论.好吧,这就是事情.使用urllib2获取内容主要是 IO绑定的.当任务受IO限制时,本机线程和多处理将具有相同的性能(线程仅在CPU受限时成为问题).是的,你可以加快速度,我自己使用python线程和10个下载程序线程完成.
基本上,您使用生产者 - 消费者模型,其中一个线程(或进程)生成要下载的URL,并且N个线程(或进程)从该队列中消耗并向服务器发出请求.
这是一些伪代码:
# Make sure that the queue is thread-safe!!
def producer(self):
# Only need one producer, although you could have multiple
with fh = open('urllist.txt', 'r'):
for line in fh:
self.queue.enqueue(line.strip())
def consumer(self):
# Fire up N of these babies for some speed
while True:
url = self.queue.dequeue()
dh = urllib2.urlopen(url)
with fh = open('/dev/null', 'w'): # gotta put it somewhere
fh.write(dh.read())
Run Code Online (Sandbox Code Playgroud)
现在,如果您正在下载非常大的数据块(数百MB)并且单个请求完全使带宽饱和,那么运行多个下载是没有意义的.您(通常)运行多次下载的原因是请求很小并且具有相对较高的延迟/开销.
| 归档时间: |
|
| 查看次数: |
5619 次 |
| 最近记录: |