Совместное использование переменной между рабочими процессами с помощью многопроцессорной обработки Python

Как я могу прочитать и обновить переменную, совместно используемую несколькими рабочими в Python?

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

def readFile(filename):
  """ Add the parent folder to the database and process the file
  """

  path_parts = os.path.split(filename)
  dirname = os.path.basename(path_parts[0])
  if dirname not in shared_variable:
    # Insert into the database


   #Other file functions


def main():
  """ Walk through files and pass each file to readFile()
  """
  queue = multiprocessing.Queue()
  pool = multiprocessing.Pool(None, init, [queue])

  for dirpath, dirnames, filenames in os.walk(PATH):

    full_path_fnames = map(lambda fn: os.path.join(dirpath, fn),
                           filenames)
    pool.map(readFile, full_path_fnames)

person ensnare    schedule 18.06.2014    source источник
comment
Решить эту проблему труднее, чем вы думаете. Прямой ответ заключается в том, что вы можете поделиться изменяемым состоянием с multiprocessing.Manager, но у вас будут некоторые серьезные состояния гонки, которые будут делать это, если вы не реализуете какое-то условие блокировки мьютекса. Если это вообще возможно, отредактируйте код так, чтобы ваши рабочие процессы вообще не зависели от общего состояния.   -  person roippi    schedule 18.06.2014


Ответы (2)


Вы можете использовать multiprocessing.Manager, чтобы помочь с этим. Это позволяет вам создать список, который можно использовать совместно между процессами:

from functools import partial
import multiprocessing

def readFile(shared_variable, filename):
  """ Add the parent folder to the database and process the file
  """

  path_parts = os.path.split(filename)
  dirname = os.path.basename(path_parts[0])
  if dirname not in shared_variable:
    # Insert into the database


   #Other file functions


def main():
  """ Walk through files and pass each file to readFile()
  """
  manager = multiprocessing.Manager()
  shared_variable = manager.list()
  queue = multiprocessing.Queue()
  pool = multiprocessing.Pool(None, init, [queue])

  func = partial(readFile, shared_variable)
  for dirpath, dirnames, filenames in os.walk(PATH):

    full_path_fnames = map(lambda fn: os.path.join(dirpath, fn),
                           filenames)
    pool.map(func, full_path_fnames)

partial используется только для того, чтобы упростить передачу shared_variable каждому вызову readFile вместе с каждым членом full_path_fnames через map.

person dano    schedule 18.06.2014

Взгляните на https://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes. Вы можете использовать разделяемую память, используя Value или Array для обмена данными между двумя или более потоками.

person Christian Berendt    schedule 18.06.2014