2012-03-29 104 views
4

我有一段代码:的Python 2.5 - 多线程for循环

for url in get_lines(file): 
    visit(url, timeout=timeout) 

它从文件中获取网址,并在for循环访问它(由的urllib2)。

是可以在少数线程中做到这一点?例如,同时访问10个。


我已经试过:

for url in get_lines(file): 
    Thread(target=visit, args=(url,), kwargs={"timeout": timeout}).start() 

但它不工作 - 没有效果,网址通常都会访问。


功能访问的简化版本:

def visit(url, proxy_addr=None, timeout=30): 
    (...) 
    request = urllib2.Request(url) 
    response = urllib2.urlopen(request) 
    return response.read() 
+1

'线程(...).start'应该产生一个新线程来运行'visit'。你怎么知道访问是连续的? – ArjunShankar 2012-03-29 13:14:16

回答

4

要扩大senderle的回答,您可以使用池类多处理可以轻松完成:

from multiprocessing import Pool 
pool = Pool(processes=5) 
pages = pool.map(visit, get_lines(file)) 

当映射函数返回时,“pages”将成为URL内容的列表。您可以将进程数量调整为适合您系统的任意数量。

+0

我刚刚意识到你在问题中指定了python 2.5,而多处理在2.6中是新的。如果你无法升级,这可能对你不太有用。道歉。 – JoeZuntz 2012-03-30 17:32:12

1

我怀疑你已经运行到Global Interpreter Lock。基本上,python中的threading无法实现并发性,这似乎是您的目标。您需要改用multiprocessing

multiprocessing被设计为具有与threading大致类似的接口,但它有一些怪癖。您的visit函数如上面写的应该正常工作,我相信,因为它是用功能性风格编写的,没有副作用。

multiprocessing中,Process类相当于threading中的Thread类。它具有所有相同的方法,所以在这种情况下它是一种直接替换。 (虽然我想你可以使用poolJoeZuntz建议 - 但我会用基本Process类第一次测试,看它是否解决了这个问题。)

+0

嗯,GIL在I/O期间发布的事实呢?:http://docs.python.org/glossary.html#term-global-interpreterlock1 – ArjunShankar 2012-03-29 13:23:49

+0

@ArjunShankar,我想到了,米不确定适用于这种情况。如果线程是纯I/O线程,可能可以使其工作可接受,但转向“多处理”应该也可以工作,并且更具可扩展性。 – senderle 2012-03-29 13:32:01

+0

同意。我只是对OP的评论感到惊讶,线程“没有影响,URL正常访问”。所以现在等待OP的跟进。 – ArjunShankar 2012-03-29 13:42:34