Как я могу запускать параллельные «задачи» в Python с SimPy, где каждая задача ожидает нескольких ресурсов? - PullRequest
2 голосов
/ 05 ноября 2019

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

В моем нынешнем виде, у меня есть задачасписок перебирается в цикле for, где вложенный цикл for затем запрашивает и захватывает необходимых «работников», а затем истекает время выполнения задачи после того, как все «работники» были захвачены.

        with self.location.request() as loc_req: # request work location
            yield loc_req # wait for work location

            for task in self.tasks[:]:
                t_duration = task.calc_duration(self)
                if t_duration == 0: # skip tasks where probability sets duration to 0
                    continue
                needs = task.resources[:]
                ## check if available workers are useful; if not, release them
                task_cur_resources = []
                for res,req in self.resources['available'].copy():
                    if res.worker_id in needs:
                        self.resources['busy'].add((res,req))
                        task_cur_resources.append((res,req))
                        needs.remove(res.worker_id)
                    else:
                        res.release(req)
                    self.resources['available'].remove((res,req))
                ## acquire all resources needed for task
                for need in needs[:]:
                    priority = len(needs) # prioritize tasks closer to meeting needs
                    res = self.location.workers[need] # set resource to worker of type need
                    req = res.request(priority) # save the request object
                    yield req # wait for resource
                    ## stash resource and request in order to release later
                    task_cur_resources.append((res, req))
                    self.resources['busy'].add((res,req))
                    needs.remove(res.worker_id)

                ## perform task with task duration timeout
                yield self.env.process(task.perform(self, t_duration))

                ## make resources available
                for worker in task_cur_resources: 
                    self.resources['busy'].remove(worker)
                    self.resources['available'].add(worker)

            for res,req in self.resources['available']:
                res.release(req)
            self.resources['available'] = set()

Проблема в том, что это не позволяет одновременно выполнять задачи. Задачи выполняются последовательно с нормально распределенными длительностями на основе входных параметров. Как я могу изменить это, чтобы разрешить выполнение задач, когда их предшественники сделаны, и рабочие доступны? Я пробовал цикл while, который повторял список задач и запланированные задачи, у которых были завершены их предшественники, но я продолжал заканчивать бесконечными циклами из-за моего очевидного неправильного использования SimPy и выходов. Есть идеи?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...