Python多处理将不会继续过去的CPU /内核数量

时间:2016-05-27 01:09:22

标签: python multiprocessing python-multiprocessing

我正在学习如何在Python中使用多个核心。在下面的脚本中,我试图从网页列表中删除标题。

import multiprocessing
import requests
from bs4 import BeautifulSoup


sites = (
        'http://penny-arcade.com/',
        'http://reallifecomics.com/',
        'http://sinfest.net/',
        'http://userfriendly.org/',
        'http://savagechickens.com/',
        'http://xkcd.com/',
        'http://duelinganalogs.com/',
        'http://cad-comic.com/',
        'http://samandfuzzy.com/',
    )


def scrape_site(q):
    url = q.get()
    try:
        page = requests.get(url)
        soup = BeautifulSoup(page.content, 'lxml')
        print url
        print soup.title.text
        print
    except:
        print url
        print "No TITLE"
        print

def run_multicore_scraper():
    workers = multiprocessing.cpu_count() # num of cpus or workers

    # put all sites into a queue
    q = multiprocessing.Queue()
    for s in sites:
        q.put(s)

    # create as many processes as workers
    processes = []
    for w in xrange(workers):
        p = multiprocessing.Process(target=scrape_site, args=(q, ))
        p.start()
        processes.append(p)

    # wait for processes to complete
    for p in processes:
        p.join()

if __name__ == '__main__':
    run_multicore_scraper()

我坚持为什么这个脚本不会遍历所有网站,而是停留在我设置的工作人员数量上。例如,我将工作器数设置为multiprocessing.cpu_count()计算的CPU数。在我的本地计算机上,即4,我的脚本只迭代到第四个网址。所以,输出看起来像这样:

http://userfriendly.org/
UserFriendly.Org

http://penny-arcade.com/
Penny Arcade

http://sinfest.net/
Sinfest

http://reallifecomics.com/
Real Life Comics ©1999-2016 Greg Dean

由于我的网站列表中有九个网址,因此我预计会有九个打印输出。如果我硬编码2作为我的工作人员数量,脚本将只打印出前2个网址。与6.相同如果我输入一个数字> len(sites),所有网址都会打印出来,但系统会挂起,大概是因为有进程已启动但从未完成,因为没有更多的网址可以从队列中处理。

我知道在我的脚本中,我创建了与工作者一样多的进程,但这也是在我创建此玩具示例时所遵循的tutorial中完成的。我认为无论我创建了多少进程,我的脚本都会遍历整个站点列表,就像教程成功完成一样。

有人可以发现为什么我的脚本不会遍历我的整个网站列表而是在第n个元素处停下来,而n =#workers?

1 个答案:

答案 0 :(得分:2)

您的scrape_site方法只搜索一个网站 - 它不会循环尝试从队列中提取越来越多的事件。你在这里派遣了4名工人:

for w in xrange(workers):
        p = multiprocessing.Process(target=scrape_site, args=(q, ))
        p.start()
        processes.append(p)

所以每个4工作人员都会启动,运行你告诉他们运行的方法,这会刮掉一个网站,然后他们就完成了。

一种方法是让scrape_site方法运行一个循环从队列中拉出站点,直到它们发现队列为空。另一种选择是使用该库中的worker pool内容而只是把那些网站清单拿去。