Я пытался распаковать несколько файлов параллельно; однако процесс просто «зависает».

Сначала я создаю 6 небольших файлов рассола:

import pickle
from multiprocessing import Pool

class A:
    x: int
    y: str
    
    def __init__(self, x:int, y:str):
        self.x = x
        self.y = y

for i in range(6):
    with open(str(i) + '.pkl', 'wb') as f:
        pickle.dump(A(i, str(i) + 'abcdefg'), f)

Далее я пытаюсь загрузить их параллельно:

def load(file):
    with open(file, 'rb') as f:
        data = pickle.load(f)

with Pool(6) as p:
    p.map(load, [str(number) + '.pkl' for number in range(6)])

Когда я запускаю это из Spyder, все 8 логических процессоров (4 «фактических» ядра) показывают загрузку, близкую к 100%, в диспетчере задач Windows; однако процесс не завершается. Если я попытаюсь остановить процесс из Spyder, мне это не удастся; единственный способ остановить это — полностью закрыть Spyder.

Однако, если я сделаю это в обычном цикле for, это займет доли секунды:

for file in [str(number) + '.pkl' for number in range(6)]:
    load(file)

Может кто-нибудь объяснить, почему это так? Кроме того, есть ли способ исправить исходный код, чтобы он действительно работал? (Файлы, которые я на самом деле пытаюсь загрузить и обработать, намного больше, поэтому мне нужен параллелизм; приведенный выше код является лишь примером, помогающим людям воспроизвести проблему).

Я прочитал несколько вопросов и ответов, связанных с загрузкой с помощью пула, например эти вопросы и ответы; однако ни один из них не помог.

0
EJoshuaS - Stand with Ukraine 4 Окт 2022 в 21:42

1 ответ

Лучший ответ

При использовании многопроцессорной обработки необходимо включить основную проверку посмотреть это

У вас сработает что-то вроде этого:

import pickle
from multiprocessing import Pool

class A:    
    def __init__(self, x:int, y:str):
        self.x = x
        self.y = y
        
def make():
    for i in range(6):
        with open(str(i) + '.pkl', 'wb') as f:
            pickle.dump(A(i, str(i) + 'abcdefg'), f)

def load(file):
    with open(file, 'rb') as f:
        data = pickle.load(f)

def main(): 
    with Pool() as p:
        p.map(load, [str(number) + '.pkl' for number in range(6)])

if __name__ == '__main__':
    make()
    main()
2
OldBill 4 Окт 2022 в 22:04
Спасибо, отлично сработало.
 – 
EJoshuaS - Stand with Ukraine
4 Окт 2022 в 22:12