Многопроцессный метод генератора, работающий только один раз для каждого процесса - PullRequest
0 голосов
/ 11 ноября 2019

У меня есть генератор, который выглядит примерно так:

class GeneratorClass():
    def __init__(self, objClient):
        self.clienteGen = objClient

    def generatorDataClient(self):
        amount = 0
        while True:
            amount += random.randint(0, 2000)
            yield amount
            sleep = random.choice([1,2,3])
            print("sleep " + str(sleep))
            time.sleep(sleep)

Затем я перебираю его, и он работает: он выполняет метод current_mean() каждый раз, когда генерируются новые данные.

def iterate_clients(pos):
    genobject4 = GeneratorClass(client_list[pos])
    generator4 = genobject4.generatorDataClient()    
    current_client = genobject1.default_client
    account1 = current_client.account
    cnt = 0
    acc_mean = 0

    for item in generator4:
        #We call a function previously defined
        acc_mean, cnt = account1.current_mean(acc_mean, item, cnt)
        print("media : " + str(acc_mean), str(cnt))

# iterate_clients(2)

И это работает, вы даете ему действительный клиент, он начинает выполнять операцию генерации, которая является скользящей средней, и, поскольку она определяется с помощью While: True, она не останавливается.

Теперь я хотел это парализовать, и мне удалось заставить его работать, но только один раз:

names = ["James", "Anna"]
client_list = [Cliente(name) for name in names]
array_length = len(client_list)


import multiprocessing
if __name__ == '__main__':
  for i in range(array_length):
    p = multiprocessing.Process(target=iterate_clients, args=(i,))
    p.start()

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

calling object with ID: 140199258213624
calling the generator
moving average : 4622.0 1
calling object with ID: 140199258211160
sleep 2
calling the generator
moving average : 8013.0 1
sleep 1

Я уверен, что код можно улучшить, но может быть, мне не хватает некоторой информации о том, как распараллелить эту проблему, в частности?

Редактировать:

Благодаря этому ответу Я попытался изменить цикл с for i in range(array_length): на while True:

И я получил что-то новое:

calling object 140199258211160
calling the generator
calling object 140199258211160
moving average : 7993.0 1
calling the generator
duerme 3
calling object 140199258211160
calling the generator
calling object 140199258211160
moving average : 8000.0 1
moving average : 7869.0 1
duerme 3
calling the generator

Иэто никогда не останавливается. Таким образом, из этого я получаю, что я делаю огромную ошибку, потому что создается только 1 процесс, и он имеет то, что кажется условием гонки, поскольку скользящая средняя движется взад-вперед и повышается только в нормальном процессе.

1 Ответ

1 голос
/ 11 ноября 2019

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

Использование .join() заставит главный процесс ждать дочерние процессы.

...

import multiprocessing

procs = []

if __name__ == '__main__':
  for i in range(array_length):
    p = multiprocessing.Process(target=iterate_clients, args=(i,))
    p.start() 
    procs.append(p)  # Hold a reference to each child process

for proc in procs:
  proc.join()  # Wait for each child process
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...