Как в Simpy синхронизировать c два процесса для запуска третьего процесса? - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь смоделировать производственный процесс на нескольких машинах. Machine1 имеет объем c объемом 1 литр. Machine2 имеет объем c вместимостью 2 литра. Мы хотим произвести 2 литра химического вещества X. Итак, мы поместили 1 литр сырья в Machine1. После этого переместите этот 1 л на Machine2. Тем временем запустите еще один раунд на Machine1 со второй партией 1L. Затем добавьте это в уже наполовину заполненный Machine2. Затем запустите Machine2, чтобы, наконец, произвести два литра. Если Machine1 занимает 3 часа, а Machine2 - 12 часов, этот процесс займет 3 + 3 + 12 = 18 часов.

Теперь мой подход следующий. Я создаю Machine1 как ресурс с емкостью 1 и Machine2 как ресурс с емкостью 2. Я wi sh, чтобы запустить Machine2 после того, как обе партии прошли через Machine1. Ниже приведен код моей попытки:

import simpy
from collections import namedtuple

Chemical = namedtuple("Chemical", "name")

X_batch1 = Chemical("X_batch1")
X_batch2 = Chemical("X_batch2")


def do_process_1(env, machine1, Chemical):
    print(f"Chemical {Chemical.name} requested Machine1 at {env.now}")
    with machine1.request() as req:
        yield req
        print(f"Chemical {Chemical.name} got into Machine1 at {env.now}")
        yield env.timeout(3)
        print(f"Chemical {Chemical.name} got out of Machine1 at {env.now}")
        # yield env.timeout(2)


def do_process_2(env, machine1, machine2, Chemicals):

    # <some condition to check if process 1 is done for both Chemicals>

    # make each batch for machine2, one after the other
    print(f"{Chemicals[0]} asks for Machine2 at {env.now}.")
    print(f"{Chemicals[1]} asks for Machine2 at {env.now}.")
    with machine2.request() as req1, machine2.request() as req2:
        yield req1 & req2
        print(f"{Chemicals[0]} gets machine2 at {env.now}.")
        print(f"{Chemicals[1]} gets Machine2 at {env.now}.")
        yield env.timeout(12)
    print(f"{Chemicals[0]} got out of machine2 at {env.now}.")
    print(f"{Chemicals[1]} got out of machine2 at {env.now}.")


env = simpy.Environment()
machine1 = simpy.Resource(env, 1)
machine2 = simpy.Resource(env, 2)

env.process(do_process_1(env, machine1, X_batch1))
env.process(do_process_1(env, machine1, X_batch2))
env.process(do_process_2(env, machine2, machine1, (X_batch1, X_batch2)))
env.run(until=60)

У меня есть два препятствия выше:

  1. Machine2 следует запрашивать только после того, как обе машины завершат работу с машиной 1. Я не уверен, как чтобы добавить это условие и куда его добавить.
  2. Machine2 нужно запрашивать дважды (разными пакетами), и после этого следует приступить к работе. Он не должен начинать работу, если есть только один запрос.

Любая помощь будет принята с благодарностью!


1 Ответ

0 голосов
/ 09 мая 2020

Я решил свой вопрос с помощью приведенного ниже кода. Короче говоря, я сохраняю процессы первой машины в переменной и передаю эту переменную второй машине. И затем я использую yield с этим процессом во втором процессе машины.

import simpy
from collections import namedtuple

Chemical = namedtuple("Chemical", "name")

X_batch1 = Chemical("X_batch1")
X_batch2 = Chemical("X_batch2")


def do_process_1(env, machine1, Chemical):
    print(f"Chemical {Chemical.name} requested Machine1 at {env.now}")
    with machine1.request() as req:
        yield req
        print(f"Chemical {Chemical.name} got into Machine1 at {env.now}")
        yield env.timeout(3)
        print(f"Chemical {Chemical.name} got out of Machine1 at {env.now}")
        # yield env.timeout(2)


def do_process_2(env, machine2, Chemicals, procs):

    yield env.all_of(procs)

    # make each batch for machine2, one after the other
    print(f"{Chemicals[0]} asks for Machine2 at {env.now}.")
    with machine2.request() as req1, machine2.request() as req2:
        yield req1 & req2
        print(f"{Chemicals[0]} gets machine2 at {env.now}.")
        yield env.timeout(12)
    print(f"{Chemicals[0]} got out of machine2 at {env.now}.")


env = simpy.Environment()
machine1 = simpy.Resource(env, 1)
machine2 = simpy.Resource(env, 2)

proc1 = env.process(do_process_1(env, machine1, X_batch1))
proc2 = env.process(do_process_1(env, machine1, X_batch2))
env.process(do_process_2(env, machine2, (X_batch1), (proc1, proc2)))
env.process(do_process_2(env, machine2, (X_batch2), (proc1, proc2)))
env.run(until=60)

...