Python 多处理将不会继续超过 CPUs/Cores 的数量
Python Multiprocessing Will Not Continue Past Number of CPUs/Cores
我正在学习如何在 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()
我不明白为什么这个脚本没有遍历所有站点而是在我设置的工作人员数量处停止。比如我把worker的数量设置为multiprocessing.cpu_count()
计算出来的CPU数量。在我的本地机器上,那是 4,我的脚本只迭代到第四个 url。所以,输出看起来像这样:
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
我希望有九个打印输出,因为我的站点列表中有九个 url。如果我将 2 硬编码为我的工人数量,脚本将只打印前 2 urls。与 6 相同。如果我输入一个数字 > len(sites)
,所有 url 都会打印出来,但随后系统挂起,大概是因为有进程启动但从未完成,因为没有更多 urls 从 queue.
处理
我知道在我的脚本中,我创建了与工作人员一样多的进程,但这也是在 tutorial 中完成的,我按照它创建了这个玩具示例。我认为我的脚本将 运行 遍历整个站点列表,而不管我创建了多少个进程,就像教程如何成功地做到这一点一样。
有人能看出为什么我的脚本没有遍历我的整个站点列表而是在 n = # workers 的第 n 个元素处停止吗?
您的 scrape_site
方法只抓取一个站点 - 它不会循环尝试从队列中提取越来越多的事件。而你正好派遣 4 名工人到这里:
for w in xrange(workers):
p = multiprocessing.Process(target=scrape_site, args=(q, ))
p.start()
processes.append(p)
因此 4 个工作人员中的每个人都将开始,运行 您告诉他们的方法 运行,抓取一个站点,然后他们就完成了。
一种方法是使用 scrape_site
方法 运行 循环从队列中拉取站点,直到他们发现队列是 empty.Another 选项是使用 worker pool 那个图书馆里的东西,然后把要抓取的网站列表交给他们。
我正在学习如何在 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()
我不明白为什么这个脚本没有遍历所有站点而是在我设置的工作人员数量处停止。比如我把worker的数量设置为multiprocessing.cpu_count()
计算出来的CPU数量。在我的本地机器上,那是 4,我的脚本只迭代到第四个 url。所以,输出看起来像这样:
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
我希望有九个打印输出,因为我的站点列表中有九个 url。如果我将 2 硬编码为我的工人数量,脚本将只打印前 2 urls。与 6 相同。如果我输入一个数字 > len(sites)
,所有 url 都会打印出来,但随后系统挂起,大概是因为有进程启动但从未完成,因为没有更多 urls 从 queue.
我知道在我的脚本中,我创建了与工作人员一样多的进程,但这也是在 tutorial 中完成的,我按照它创建了这个玩具示例。我认为我的脚本将 运行 遍历整个站点列表,而不管我创建了多少个进程,就像教程如何成功地做到这一点一样。
有人能看出为什么我的脚本没有遍历我的整个站点列表而是在 n = # workers 的第 n 个元素处停止吗?
您的 scrape_site
方法只抓取一个站点 - 它不会循环尝试从队列中提取越来越多的事件。而你正好派遣 4 名工人到这里:
for w in xrange(workers):
p = multiprocessing.Process(target=scrape_site, args=(q, ))
p.start()
processes.append(p)
因此 4 个工作人员中的每个人都将开始,运行 您告诉他们的方法 运行,抓取一个站点,然后他们就完成了。
一种方法是使用 scrape_site
方法 运行 循环从队列中拉取站点,直到他们发现队列是 empty.Another 选项是使用 worker pool 那个图书馆里的东西,然后把要抓取的网站列表交给他们。