Совместное использование переменной между процессами - PullRequest
7 голосов
/ 25 марта 2012

У меня есть функция загрузчика, которая загружает несколько файлов параллельно.Я использую multiprocessing.Pool.map_async для загрузки разных кусков одного и того же файла.Я хотел бы показать строку состояния загрузки.Для этого мне нужно знать общее количество байт, которые уже были загружены (total_bytes_dl).

    pool = multiprocessing.Pool(processes)
    mapObj = pool.map_async(f, args)

    while not mapObj.ready():
        status = r"%.2f MB / %.2f MB" % (total_bytes_dl / 1024.0 / 1024.0, filesize / 1024.0 / 1024.0,)
        status = status + chr(8)*(len(status)+1)
        print status,
        time.sleep(0.5)

Есть ли способ установить переменную, которая будет использоваться всеми этими процессами И основным процессом, так что каждый процесс может добавить количество только что загруженных байтов?

Ответы [ 4 ]

4 голосов
/ 29 марта 2012

Решением было запустить новый процесс и передать значение общего типа:

from ctypes import c_int
import dummy

shared_bytes_var = multiprocessing.Value(c_int)

def Func(...):
    ....
    pool = multiprocessing.Pool(initializer=_initProcess,initargs=(shared_bytes_var,))
    ....

def _initProcess(x):
  dummy.shared_bytes_var = x
2 голосов
/ 31 марта 2012

Используйте объект Queue, выделенный следующим образом:

que = multiprocessing.Manager().Queue()

Передайте эту переменную рабочим, и они могут использовать que.put(bytes), чтобы периодически сообщать, сколько они загрузили с момента последнего отчета.Затем вы просто проверяете размер очереди и извлекаете все входящие отчеты:

downloaded = 0
while not mapObj.ready():
    for _ in range(q.qsize()):
        downloaded += q.get()
    print downloaded, r"bytes downloaded\r",
    time.sleep(0.5)

Примечание: Хотя модуль также предоставляет метод multiprocessing.Queue(), он не полностью эквивалентен multiprocessing.Manager().Queue().См. этот вопрос и ответ.

1 голос
/ 25 марта 2012

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

см: http://docs.python.org/library/multiprocessing.html#shared-ctypes-objects

0 голосов
/ 25 марта 2012

Вы можете использовать многопроцессный объект Queue, который рабочие могут использовать для отправки данных о состоянии.Ваш основной процесс должен будет прочитать записи статуса из очереди и соответственно обновить статус.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...