многопроцессорность Python - что не так? - PullRequest
0 голосов
/ 22 ноября 2018

Мне нужно загрузить файлы на сервер, это занимает слишком много времени (много маленьких файлов).Я пробовал многопроцессорную работу, но по какой-то причине она не работает.«Результат» не изменяется при вызове через пул.Если я вызываю функцию только для одного объекта, это меняет результат.Если я выполню команду print (self) с удалением (def repr ), я вижу, что процесс работает с другим объектом (копией?). Как это исправить?

import time
from builtins import range, enumerate, str
from multiprocessing import Pool

class UploadJob():
    def __init__(self, value):
        self.value = value
        self.result = None

    def run(self):
        print("start",self.value)
        time.sleep(1)#simulate uploading
        print("end",self.value)
        self.result = str(self.value) + "_fromServer" #save some ID for file

    def __repr__(self):
        return str(self.value)+"-"+str(self.result)


job = UploadJob(99)
print(job)
job.run()
print(job)
print()


arr = [x for x in range(0,5)]
for idx,val in enumerate(arr):
    arr[idx] = UploadJob(val)

print(arr)


def func(val:UploadJob):
    val.run()


pool = Pool()
for val in arr:
    res = pool.apply_async(func, args=(val,))

pool.close()
pool.join()

print(arr)

вывод:

99-None
start 99
end 99
99-99_fromServer

[0-None, 1-None, 2-None, 3-None, 4-None]
start 0
start 1
start 2
start 3
start 4
end 0
end 1
end 2
end 3
end 4
[0-None, 1-None, 2-None, 3-None, 4-None]

РЕДАКТИРОВАТЬ: Если я изменю func для возврата значения и использую pool.map, он работает правильно, исходный массив не изменяется, но копияправильный.Если UploadJob будет иметь файл в виде bytearray, будет ли процесс его копировать?

def func(val:UploadJob):
    val.run()
    return val

with Pool() as pool:
    arr1 = pool.map(func, arr)

print(arr)#prints the original result with None
print(arr1)#prints the correct values

1 Ответ

0 голосов
/ 22 ноября 2018

с pool.apply_async(func, args=(val,)), val отправляет дочернему процессу pickle/unpickle, таким образом, это другой объект в дочернем процессе, хотя они имеют одинаковое значение.изменение состояния в дочернем процессе не может повлиять на родительский процесс, поскольку они имеют отдельное пространство памяти.

...