Невозможно использовать многопроцессорную разделяемую память для сохранения вывода из многопроцессорной функции - PullRequest
2 голосов
/ 05 февраля 2020

Я пишу программу для извлечения информации из Интернета и сохранения ее в списке Python. Я использую многопроцессорный метод для извлечения информации и испытываю проблемы с сохранением списка вывода для дальнейшей обработки. Это мой код:

import multiprocessing

def web_scrape1():
    #some codes to scrape the web output 3 lists
    global sub_list1a, sub_list2a, sub_list3a
    sub_list1a.append(scrape1)
    sub_list2a.append(scrape2)
    sub_list3a.append(scrape3)

def web_scrape2():
    #some codes to scrape the web output 3 lists
    global sub_list1b, sub_list2b, sub_list3b
    sub_list1b.append(scrape1)
    sub_list2b.append(scrape2)
    sub_list3b.append(scrape3)

def master_scraper():
    ws1 = multiprocessing.Process(target=web_scrape1)
    ws2 = multiprocessing.Process(target=web_scrape2)

    ws1.start()
    ws2.start()
    ws1.join()
    ws2.join()

    global master_list1, master_list2, master_list3

    master_list1 = sub_list1a + sub_list1b
    master_list2 = sub_list2a + sub_list2b
    master_list3 = sub_list3a + sub_list3b

def postprocessing():
    #some codes to process the lists
    print(master_list1) # Output []
    print(master_list2) # Output []
    print(master_list3) # Output []

def main():
  master_scraper()
  postprocessing()

if __name__ == '__main__':
  multiprocessing.freeze_support()
  main()

вывод для приведенного выше кода просто:

[]
[]
[]

Я попытался назначить весь список общей памяти, используя что-то вроде этого multiprocessing.Array('b', sub_list1a) внутри функции web_scape1(), master_scraper() и main(), но список все еще возвращается как [].

Надеюсь получить помощь здесь.

1 Ответ

3 голосов
/ 13 февраля 2020

В multiprocessing вы не можете использовать глобальные переменные, потому что процессы занимают свою собственную область памяти, изменения внутри каждого процесса независимы. Самый простой способ выполнить то, что вы пытаетесь - это использовать Manager для связи между процессами. Вы можете создать output_container и передать его каждой функции, чтобы они могли получить к ней доступ и изменить ее. Например:

import multiprocessing as mp


def web_scrape1(output_container: list):
    sample_text = 'value from web_scrape1'
    output_container.append(sample_text)


def web_scrape2(output_container: list):
    sample_text = 'value from web_scrape2'
    output_container.append(sample_text)


if __name__ == "__main__":
    output_container = mp.Manager().list()

    worker1 = mp.Process(target=web_scrape1, args=(output_container,))
    worker2 = mp.Process(target=web_scrape2, args=(output_container,))

    worker1.start()
    worker2.start()

    worker1.join()
    worker2.join()

    print(output_container)
    >>> ['value from web_scrape1', 'value from web_scrape2']

Более подробную информацию можно найти в документах .

...