使用Python中的多处理将项目附加到列表中

时间:2017-12-29 21:01:11

标签: python multiprocessing

得到这段代码:

def get_spain_accomodations():
    pool = Pool()
    links = soup.find_all('a', class_="hotel_name_link url")
    pool.map(get_page_links, links)

    #for a in soup.find_all('a', class_="hotel_name_link url"):
    #    hotel_url = "https://www.booking.com" + a['href'].strip()
    #    hotels_url_list.append(hotel_url)

def get_page_links(link):
     hotel_url = "https://www.booking.com" + link['href'].strip()
     hotels_url_list.append(hotel_url)

由于某种原因,hotel_url未被附加到列表中。如果我尝试使用注释循环它实际上工作,但不是map()函数。我还为每个get_page_links调用打印了hotel_url并且它有效。我不知道发生了什么事。以下是函数调用。

init_BeautifulSoup()
get_spain_accomodations()
#get_hotels_wifi_rating()

for link in hotels_url_list:
    print link

执行代码时没有错误,但没有打印链接列表。

1 个答案:

答案 0 :(得分:0)

了解流程在隔离的内存区域中运行非常重要。每个流程都有{strong>他们自己的实例 hotels_url_list,并且没有(简单)方式"坚持"这些值进入父进程' list:如果在父进程中创建了list的实例,那么实例与子进程使用的不同:当你执行.fork()时(也就是创建一个子进程) ),父进程的内存在子进程上克隆。因此,如果父级在list变量中有hotels_url_list的实例,那么您在该子级中也会有list的实例(也称为hotels_url_list)过程但它们不一样(它们会在内存中占据不同的区域)。

线程不会发生这种情况。他们确实共享记忆。

我会说(这不像我在这里的专家那样),在这种情况下,传播流程的规范方式是Queue:子流程将事物放入队列,父进程抓住它们:

from multiprocessing import Process, Queue


def get_spain_accomodations():
    q = Queue()
    processes = []
    links = ['http://foo.com', 'http://bar.com', 'http://baz.com']
    hotels_url_list = []
    for link in links:
        p = Process(target=get_page_links, args=(link, q,))
        p.start()
        processes.append(p)
    for p in processes:
        p.join()
        hotels_url_list.append(q.get())
    print("Collected: %s" % hotels_url_list)


def get_page_links(link, q):
    print("link==%s" % link)
    hotel_url = "https://www.booking.com" + link
    q.put(hotel_url)


if __name__ == "__main__":
    get_spain_accomodations()

这将输出前面带有https://www.booking.com的每个链接,这是在独立进程上发生的待处理事件:

link==http://foo.com
link==http://bar.com
link==http://baz.com
Collected: ['https://www.booking.comhttp://foo.com', 'https://www.booking.comhttp://bar.com', 'https://www.booking.comhttp://baz.com']

我不知道它是否会对你有所帮助,但对我而言,它有助于将队列视为一个共享文件"这两个过程都知道。想象一下,你有两个完整的不同程序,其中一个知道必须将事物写入名为/tmp/foobar.txt的文件中,另一个知道必须从名为/tmp/foobar.txt的文件中读取。通过这种方式,他们可以“沟通”#34;彼此。这段话只是一个比喻" (虽然这几乎是Unix pipes的工作原理)......不像队列那样工作,但也许它有助于理解这个概念? Dunno,真的,也许我让它更令人困惑......

另一种方法是使用主题并收集其返回值,如here所述。