簡體   English   中英

Python多處理將無法持續超過CPU /核數

[英]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個網址。 與6相同。如果我輸入數字> len(sites) ,則所有URL將被打印出來,但是系統掛起,大概是因為有進程開始了,但從未結束,因為隊列中沒有更多的URL要處理。

我知道在我的腳本中,我創建的進程與我擁有的工人一樣多,但是在創建此玩具示例的本教程中也是如此。 我以為我的腳本將遍歷整個站點列表,而不管我創建了多少個進程,就像本教程如何成功做到這一點一樣。

有人可以發現為什么我的腳本沒有遍​​歷整個站點列表,而是在n =#worker的第n個元素處停下來嗎?

您的scrape_site方法只scrape_site一個站點-它不會循環嘗試從隊列中提取越來越多的事件。 您恰好在這里派遣了4名工人:

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

這樣4個工作線程中的每個工作人員都將啟動,運行您告訴他們的運行方法,這將刮取一個站點,然后完成。

一種方法是讓scrape_site方法運行一個循環,將站點從隊列中拉出,直到發現隊列為空為止。另一種選擇是使用該庫中的工作池內容,然后將要刮除的站點列表交給站點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM