Room_on
В примере Value и Array передаются в один процесс, а мне нужно передать их в несколько процессов + список, значения из которого будут разбираться процессами и запускать одновременное выполнение функции.
тут как раз разницы никакой, вы можете Value и Array передать в два, три… миллион процессов с ровно тем же результатов.
Room_on
Я не понимаю, как использовать их вместе с pool.map
а вот с pool.map там все намного веселее, если вы попытаетесь передать их так же как и “простом примере” то получите исключение типа такого:
RuntimeError: Synchronized objects should only be shared between processes through inheritance
Вобщемто нормального решения этой проблемы пока не существует(ну или я пока не нашел его).
но есть пару -тройку решений. Одно совсем костыльное с использованием globals
from multiprocessing import Pool, Value
from datetime import datetime
counter = None
start_time = None
def init(cntr, start_t):
#инициализатор для каждого процесса
global counter
global start_time
counter = cntr
start_time = start_t
def main(link):
with counter.get_lock():
counter.value += 1
print(counter.value, link, start_time)
if __name__ == '__main__':
counter = Value('i', 0)
start_time = datetime.now()
links = ['a','b','c','d', 'e', 'f']
m = 3
with Pool(processes=m, initializer = init, initargs = (counter, start_time)) as pool:
pool.map(main, links)
pool.close()
pool.join()
второй менее костыльный, уже без использования globals, но все равно, ИМХО, немного через #опу.
from multiprocessing import Pool, Value
from datetime import datetime
def init(func, counter, start_time):
#инициализатор для каждого процесса
# передаем счетчик в тупую нашей функции, ведь функция это тоже обьект :)
func.counter = counter
func.statr_time = start_time
def main(link):
counter = main.counter # вобщем это необязательно, можно просто
start_time = main.start_time # писать везде main.counter или main.start_time
with counter.get_lock(): # всемсто counter и start_time
counter.value += 1 #
print(counter.value, link, start_time)
if __name__ == '__main__':
counter = Value('i', 0)
start_time = datetime.now()
links = ['a','b','c','d', 'e', 'f']
m = 3
with Pool(processes=m, initializer = init, initargs = (main, counter, start_time)) as pool:
pool.map(main, links)
pool.close()
pool.join()
Но если использовать Manager() то оно вобщем вполне работает “втупую”, Это ИМХО, вообще некостыльный и самый кошерный метод, единственный минус Manager() таки помедленее будет чем просто Value.
from multiprocessing import Pool, Manager
from datetime import datetime
from itertools import repeat
def main(link, counter, start_time):
counter.value += 1
print(counter.value, link, start_time)
if __name__ == '__main__':
manager = Manager()
counter = manager.Value('i', 0)
start_time = datetime.now()
links = ['a','b','c','d', 'e', 'f']
m = 3
with Pool(processes=m) as pool:
pool.starmap(main, zip(links, repeat(counter), repeat(start_time)))
pool.close()
pool.join()
вывод :
1 a 2019-02-28 12:04:35.360442
2 b 2019-02-28 12:04:35.360442
3 c 2019-02-28 12:04:35.360442
4 d 2019-02-28 12:04:35.360442
5 e 2019-02-28 12:04:35.360442
6 f 2019-02-28 12:04:35.360442