【问题标题】:From synchronous to asynchronous "Processing" when working with list chunks使用列表块时从同步到异步“处理”
【发布时间】:2014-09-28 14:42:35
【问题描述】:

我通过Process 类使用多处理模块来执行一些不受 cpu 限制的任务,例如I/O 或 Web 请求。如果任务花费的时间太长,CPU 会达到 100% 的使用率(所有线程都在等待数据返回)。我怀疑异步执行解决方案,但我从未做过这样的事情。我正在使用的代码类似于以下内容,其中我有一个巨大的列表,每个进程都在一个块上工作。

您能在这个方向上提出建议吗?

提前致谢!!

import multiprocessing
def getData(urlsChunk, myQueue):

    for url in urlsChunk:
       fp = urllib.urlopen(url)
       try:
           data = fp.read()
           myQueue.put(data)
       finally:
           fp.close()

    return myQueue

manager = multiprocessing.Manager()
HUGEQ = manager.Queue()
urls = ['a huge list of url items']
chunksize = int(math.ceil(len(urls) / float(nprocs)))
for i in range(nprocs):
    p = Process(
                target = getData, # This is my worker
                args=(urls[chunksize * i:chunksize * (i + 1)],
                        MYQUEUE
                    )
                )
    processes.append(p)
    p.start()

for p in processes:
    p.join()

while True:
    try:
        MYQUEUEelem = MYQUEUE.get(block=False)
    except Empty:
        break
    else:
        'do something with the MYQUEUEelem'

【问题讨论】:

  • 我不明白底部的while循环。你不应该打一个阻塞电话吗?当子进程第一次落后时,父进程会得到一个 Empty 并跳出处理循环。
  • 在获取 url 时分块不是一个好主意。分块通过一次发送多个请求来减少父/子开销。不利的一面是孩子现在必须处理所有这些。如果某些 url 很慢,则该客户端上的剩余 url 将不得不等待,即使另一个子进程已完成并准备处理更多。
  • 您能多解释一下blocking call 和子进程是什么意思吗?
  • 您正在创建一组同步获取 url 的子进程。 getData 需要 1 个 url,发出请求,等待请求完成并返回结果。假设您有 100 个网址和 10 个孩子。您可以给每个孩子 10 个网址(块)。但是有些 url 比其他 url 需要更长的时间(可能更长),所以有些孩子比其他孩子更早完成。如果您一次只提交 1 个 url(没有块),那么早完成的孩子会获得额外的 url,您可以更快地完成。

标签: python windows python-2.7 asynchronous multiprocessing


【解决方案1】:

使用multiprocessing.Pool,您的代码可以简化:

import multiprocessing

def getData(url):
    fp = urllib.urlopen(url)
    try:
        return fp.read()
    finally:
        fp.close()

if __name__ == '__main__':  # should protect the "entry point" of the program
    urls = ['a huge list of url items']
    pool = multiprocessing.Pool()
    for result in pool.imap(getData, urls, chunksize=10):
        # do something with the result

【讨论】:

  • @Thoth,我认为这不会占用 100% cpu,除非您在 do something with the result 部分进行一些繁重的计算。
  • do something with the results 正在将数据保存在 txt 文件中。这合乎逻辑吗?
  • @Thoth,您的意思是所有 url 的内容都放在一个文件中吗?还是在单独的文件中?两者都有可能。
  • 也许我的帖子基于错误的假设。 cpu 开销的原因不是 web 响应的线程空闲情况。然而,小——不是 cpu 昂贵——但计算量大,导致了这种情况。也许是基于错误假设的问题。
  • 不管怎样,你的sn-p是异步的吗?我的意思是在网络调用之后线程继续做其他事情直到数据返回?此外,我们可以手动制作这张地图(imap)吗?我想更笼统地回答这个问题,而不是在必要时删除它(在您的许可下)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 2016-10-16
  • 2019-10-27
相关资源
最近更新 更多