Многопроцессорная обработка с использованием разделяемой памяти

python arrays multiprocessing shared-memory

765 просмотра

2 ответа

Может ли кто-нибудь предоставить мне пример кода для совместного использования доступного для записи массива или списка среди пула рабочих процессов или даже индивидуально порожденных процессов, использующих многопроцессорный модуль python с использованием блокировок? Мой код ниже порождает 2 процесса, один из которых должен вывести «1», а другой должен вывести «2» в общий массив. Однако, когда я пытаюсь распечатать элементы массива после обработки, он дает мне только список из 0. Куда я иду не так? Я хочу, чтобы доступная для записи структура данных была распределена между несколькими процессами.

Ниже мой код:

import multiprocessing

arr=multiprocessing.Array('i',10,lock=True)
lock=multiprocessing.RLock()

def putitin(n):
    for i in range(5):
        lock.acquire()
        arr.append(n)
        lock.release()
    return

p1=multiprocessing.Process(target=putitin,args=(1,))
p2=multiprocessing.Process(target=putitin,args=(2,))

p1.start()
p2.start()

p1.join()
p2.join()

for i in range(10):
    print(arr[i])
Автор: Vedant7 Источник Размещён: 08.11.2019 11:25

Ответы (2)


1 плюс

Одна потенциальная проблема с вашим кодом заключается в том, что для использования multiprocessingв Windows вам нужно поместить код для основного процесса в if __name__ == '__main__':блок. См. Подраздел « Безопасный импорт основного модуля» раздела « Windows » руководства по многопроцессорному программированию .

Другой важный момент - вы пытаетесь разделить глобальную переменную между процессами. который не будет работать, потому что каждый работает в своем собственном неразделенном пространстве памяти, поэтому у каждого подпроцесса есть свой собственный arr. (Переменные, которые являются только константами уровня модуля, все в порядке)

Наконец, a multiprocessing.Arrayимеет фиксированный размер и не имеет extend()метода, который ваш код пытается использовать в putitin()функции - поэтому, похоже, вам также нужен контейнер для записи и изменения размера (который упорядочен и, возможно, доступен через целочисленные индексы).

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

import multiprocessing

def putitin(lst, value):
    for i in range(5):
        lst.append(value)

if __name__ == '__main__':
    manager = multiprocessing.Manager()
    lst = manager.list()

    p1 = multiprocessing.Process(target=putitin, args=(lst, 1))
    p2 = multiprocessing.Process(target=putitin, args=(lst, 2))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    for i in range(len(lst)):
        print(lst[i])

Выход:

1
1
1
1
1
2
2
2
2
2
Автор: martineau Размещён: 20.08.2016 03:47

0 плюса

Несколько проблем, которые я нашел в вашем коде. Прежде всего, кажется хорошей идеей передать все общие ресурсы потомкам и использовать их if __name__ == '__main__'. Во-вторых, я не думаю, что multiprocessing.Arrayесть append()метод (по крайней мере, он не работал для меня на Python2 и Python3). В-третьих, поскольку вы используете, lock=Trueя не думаю, что вам нужны дополнительные блокировки.

Если вам нужно добавить значения в массив, я бы использовал отдельную переменную Counter (см. Код ниже).

import multiprocessing


def putitin(n, arr, counter):
        for i in range(5):
            with counter.get_lock():
                index = counter.value
                counter.value += 1
            arr[index] = n

if __name__ == '__main__':
        arr = multiprocessing.Array('i', 10,lock=True)
        counter = multiprocessing.Value('i', 0, lock=True)
        p1 = multiprocessing.Process(target=putitin,args=(1, arr, counter))
        p2 = multiprocessing.Process(target=putitin,args=(2, arr, counter))

        p1.start()
        p2.start()

        p2.join()
        p1.join()

        for i in range(10):
            print(arr[i])

Сказав это, какова ваша цель высокого уровня? Чего вы пытаетесь достичь с этим? Может быть можно использовать multiprocessing.Pool?

Автор: Stanislau Hlebik Размещён: 20.08.2016 03:45
Вопросы из категории :
32x32