import random
from multiprocessing import Pool
my_list = [1,2,3,4,5,6,7,8,9]
used = []
def test(i):
indx = random.randint(0,len(my_list)-1)
while my_list[indx] in used: #ищу элемент, который ранее не использовался
indx = random.randint(0,len(my_list)-1)
used.append(my_list[indx]) #добавляю элемент в список используемых, чтобы избежать повторного использования
print(my_list[indx]) #вывожу уникальный элемент на печать
with Pool(4) as p:
p.map(test, [1,2,3,4,5,6,7])
process_1
никак не пересекаются с переменными из process_2
. Что-бы шарить данные между процессами нужно использовать Manager.from multiprocessing import Pool, Manager
def rotator(data_list):
data = data_list.pop(0)
data_list.append(data)
return data
def print_data(data_list):
data = rotator(data_list)
print(data)
if __name__ == "__main__":
manager = Manager()
data_list = manager.list()
for x in range(5):
data_list.append(x)
with Pool(4) as pool:
for _ in range(10):
pool.apply_async(print_data, [data_list])
pool.close()
pool.join()
0
1
2
3
4
0
1
2
3
4
4
2
0
1
Когда задача завершается
manager.list()
создает самый обычный список, который вы можете шарить между процессами. Т.е. все, что вам нужно - это передать его в качестве аргумента нужной функции. Да, иногда возникает лапша с передачей подобных аргументов от функции к функции, что-бы достигнуть "цели", но это условность неуместного использования. Лучше делать подобные решения асинхронно, а если нужен именно процесс для обработки - запускать его в ProcessPoolExecutor. pop()
. Если элемента не будет в списке, то и взять его процесс не сможет =)pop()
, то будет ошибка IndexError
. from multiprocessing import Pool, Manager
import random, time
my_list = [1,2,3,4,6,7,8,9,10,11]
def rotator(used):
index = random.randint(0,len(my_list)-1)
while my_list[index] in used: #данный лист один для всех, там актуальна инфа
index = random.randint(0,len(my_list)-1)
used.append(my_list[index])
return my_list[index]
def print_data(used):
data = rotator(used)
print(data)
if __name__ == "__main__":
manager = Manager()
used = manager.list() # создаем лист used, который будет доступен всем процессам
with Pool(4) as pool:
for _ in range(10):
pool.apply_async(print_data, [used]) # передаем лист used в ф-цию для каждого процесса
pool.close()
pool.join()
def rotator(used):
index = random.randint(0,len(my_list)-1)
while my_list[index] in used:
index = random.randint(0,len(my_list)-1)
used
оно отсутствует, и когда все эти 4 процесса уже взяли какое-то значение только после этого оно добавляется в used
. Я показал вам пример как производить ротацию, что бы гарантировать то, что 2 процесса не будут обращаться к одному и тому-же объекту, нужно что бы этого объекта просто не было в списке. Вы можете играться с Lock, но тогда конкретно в вашем случае поток выполнения будет блокироваться пока 1 процесс не закончит операцию и только затем начнет обрабатывать следующий процесс. Абсурд, т.к. по сути вы превратите многопроцессорный-параллельный скрипт в многопроцессорный-последовательный. import rotator, time, random
from multiprocessing import Pool, Manager
friends = ['Vasya', 'Petya', 'Kolya', 'Sasha', 'Ivan', 'Alex', 'Semen', 'Goga Aka Gosha']
def drinking_with_friend(friends_list):
data = friends_list.pop(0)
interval = random.random() * 10
print('Start Drinking with {:>20} time for drinking (duration {} )'.format(data, interval))
time.sleep(interval)
friends_list.append(data)
print('Finish Drinking with {:>19} time for drinking (duration {} )'.format(data, interval))
if __name__ == "__main__":
manager = Manager()
friends_list = manager.list(friends)
with Pool(4) as pool:
for _ in range(10):
pool.apply_async(drinking_with_friend, [friends_list])
pool.close()
pool.join()
exit()
Start Drinking with Vasya time for drinking (duration 5.154979043445119 )
Start Drinking with Petya time for drinking (duration 0.0003130800248030141 )
Start Drinking with Kolya time for drinking (duration 1.833550237898618 )
Finish Drinking with Petya time for drinking (duration 0.0003130800248030141 )
Start Drinking with Sasha time for drinking (duration 6.215763259101572 )
Start Drinking with Ivan time for drinking (duration 9.88406377301575 )
Finish Drinking with Kolya time for drinking (duration 1.833550237898618 )
Start Drinking with Alex time for drinking (duration 3.848374725013499 )
Finish Drinking with Vasya time for drinking (duration 5.154979043445119 )
Start Drinking with Semen time for drinking (duration 9.993493984622905 )
Finish Drinking with Alex time for drinking (duration 3.848374725013499 )
Start Drinking with Goga Aka Gosha time for drinking (duration 1.5210977154160177 )
Finish Drinking with Sasha time for drinking (duration 6.215763259101572 )
Start Drinking with Petya time for drinking (duration 0.33348320324053105 )
Finish Drinking with Petya time for drinking (duration 0.33348320324053105 )
Start Drinking with Kolya time for drinking (duration 2.7868309945262726 )
Finish Drinking with Goga Aka Gosha time for drinking (duration 1.5210977154160177 )
Finish Drinking with Kolya time for drinking (duration 2.7868309945262726 )
Finish Drinking with Ivan time for drinking (duration 9.88406377301575 )
Finish Drinking with Semen time for drinking (duration 9.993493984622905 )
pop()
получат IndexError
и умрут, ну лучше так не делает и обрабатывать исключение и нормально завершать процесс. def drinking_with_friend(friends_list):
try:
data = friends_list.pop(0)
except IndexError:
print('There are no more sober friends')
return False
interval = random.random() * 10
print('Start Drinking with {:>20} time for drinking (duration {} )'.format(data, interval))
time.sleep(interval)
print('Finish Drinking with {:>19} time for drinking (duration {} )'.format(data, interval))
Start Drinking with Vasya time for drinking (duration 0.525207635674314 )
Start Drinking with Petya time for drinking (duration 8.101208126205927 )
Start Drinking with Kolya time for drinking (duration 5.656888553205503 )
Start Drinking with Sasha time for drinking (duration 9.985692547228792 )
Finish Drinking with Vasya time for drinking (duration 0.525207635674314 )
Start Drinking with Ivan time for drinking (duration 6.944745503696382 )
Finish Drinking with Kolya time for drinking (duration 5.656888553205503 )
Start Drinking with Alex time for drinking (duration 8.269980798554679 )
Finish Drinking with Ivan time for drinking (duration 6.944745503696382 )
Start Drinking with Semen time for drinking (duration 7.068649522212147 )
Finish Drinking with Petya time for drinking (duration 8.101208126205927 )
Start Drinking with Goga Aka Gosha time for drinking (duration 5.178367620321175 )
Finish Drinking with Sasha time for drinking (duration 9.985692547228792 )
There are no more sober friends
There are no more sober friends
Finish Drinking with Goga Aka Gosha time for drinking (duration 5.178367620321175 )
Finish Drinking with Alex time for drinking (duration 8.269980798554679 )
Finish Drinking with Semen time for drinking (duration 7.068649522212147 )