Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用多处理将项追加到列表_Python_Multiprocessing - Fatal编程技术网

在Python中使用多处理将项追加到列表

在Python中使用多处理将项追加到列表,python,multiprocessing,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://w

在这段代码中:

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电话打印了酒店的url,这很有效。我不知道发生了什么事。下面是函数调用

init_BeautifulSoup()
get_spain_accomodations()
#get_hotels_wifi_rating()

for link in hotels_url_list:
    print link

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

了解进程在内存的隔离区域中运行是很重要的。每个进程都有自己的实例
hotels\u url\u list
,没有(简单的)方法将这些值“粘贴”到父进程的列表中:如果在父进程中创建
list
的实例,则该实例与子进程使用的实例不同:当您执行
.fork()
(也称为创建子进程),父进程的内存在子进程上被克隆。因此,如果父进程在
hotels\u url\u list
变量中有一个
list
的实例,您还将有一个
list
的实例(也称为
hotels\u url\u list
)在子进程中,但它们将不相同(它们将占用内存中的不同区域)

线程不会发生这种情况。它们确实共享内存

我想说(我不是这里的专家),在这种情况下,传递进程的标准方式是:子进程将事物放入队列,父进程将它们捕获:

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
的文件中读取内容。这样,它们可以相互“通信”。这一段只是一个例子“隐喻”(虽然这就是工作原理)…不像队列那样工作,但也许它有助于理解这个概念?不知道,真的,也许我把它弄得更混乱了


另一种方法是使用线程并收集它们的返回值,如前所述。

在进程之间共享状态并不简单。为什么不使用
pool.map
创建列表呢?换句话说,不要执行
hotels\u url\u list.append(hotel\u url)
,只需
获取页面链接返回酒店url
,然后保存
pool.map(…)