【问题标题】:Python 2.5 - multi-threaded for loopPython 2.5 - 多线程 for 循环
【发布时间】:2012-03-29 12:53:34
【问题描述】:

我有一段代码:

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

它从文件中获取 URL 并在 for 循环中访问它(通过 urllib2)。

可以在几个线程中做到这一点吗?例如,同时访问 10 次。


我试过了:

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

但是它不起作用-没有效果,可以正常访问URL。


函数visit的简化版:

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

【问题讨论】:

  • Thread(...).start 应该产生一个新线程来运行visit。你怎么知道访问是顺序的?

标签: python multithreading for-loop


【解决方案1】:

要扩展 senderle 的答案,您可以在多处理中使用 Pool 类来轻松做到这一点:

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

当 map 函数返回时,“pages”将是 URL 内容的列表。您可以将进程数调整为适合您系统的任何值。

【讨论】:

  • 我刚刚意识到您在问题中指定了 python 2.5,而多处理是 2.6 中的新功能。如果您无法升级,这可能对您没有那么有用。道歉。
【解决方案2】:

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

multiprocessing 被设计成与threading 有一个大致相似的接口,但它有一些怪癖。你上面写的visit函数应该正常工作,我相信,因为它是用函数式编写的,没有副作用。

multiprocessing 中,Process 类等效于threading 中的Thread 类。它具有所有相同的方法,因此在这种情况下它是一个替代品。 (虽然我想你可以按照JoeZuntz 的建议使用pool——但我会先用基本的Process 类进行测试,看看它是否能解决问题。)

【讨论】:

  • 嗯,GIL 在 I/O 期间释放呢?:docs.python.org/glossary.html#term-global-interpreter-lock
  • @ArjunShankar,我想到了这一点,但我不确定这是否适用于这种情况。如果线程是纯 I/O 线程,它可能会以可接受的方式工作,但转移到 multiprocessing 也应该可以工作,并且更具可扩展性。
  • 同意。我只是对 OP 的评论感到惊讶,即线程“没有效果,可以正常访问 URL”。所以现在等待 OP 跟进。
猜你喜欢
  • 2023-03-07
  • 2017-06-13
  • 2021-02-23
  • 2016-12-15
  • 1970-01-01
  • 2011-08-20
  • 2011-02-13
  • 2013-04-13
  • 1970-01-01
相关资源
最近更新 更多