如果另一个进程在simpy中启动,如何暂停进程的执行



我正在尝试使用simpy对银行的服务流程进行建模(例如(。不过,我想插入一个午休时间。然而,使用中断功能,调用被中断,不再被处理,并且在中断之后,请求继续被处理。有什么方法可以用simpy来模拟这种情况吗?

class BANCO(object):
def __init__(self, env, n_caixas, n_prioritario):
self.env = env
self.caixa_prioritário = simpy.PriorityResource(env, n_prioritario)
self.quebrado = False

def tempo_quebra(self, media):
return random.expovariate(media)
def processo_caixa(env, banco, idade, id):
#Solicita um caixa
print('Cliente', id, 'de', idade, 'anos entrou no banco às', env.now)
# print('Cliente', id, 'de', idade, 'anos solicitou um caixa às', env.now)
try:
with banco.caixa_prioritário.request() as caixa:
yield caixa
print('Cliente', id, 'de', idade, 'anos começou o atendimento', env.now)
yield env.timeout(2)
print('Cliente', id, 'de', idade, 'anos terminou o atendimento', env.now)
yield env.timeout(0.2)
except simpy.Interrupt:
print('caixa indisponível')
def manutencao(env, banco, processo):
while True:
yield env.timeout(3)
if not(banco.quebrado) and processo.is_alive:
print('Pausa para almoço', env.now)
banco.quebrado = True
processo.interrupt()
yield env.timeout(3)
print('Fim do almoço', env.now)
banco.quebrado = False
def rodar(env, n_caixas, n_prioritario):
banco = BANCO(env, n_caixas, n_prioritario)
id=1
while True:
idade = np.random.triangular(20,35,90)
processo = env.process(processo_caixa(env, banco, idade, id))
# print(processo.is_alive)
env.process(manutencao(env, banco, processo))
yield env.timeout(np.random.standard_exponential())
id+=1
N_CAIXAS = 1
N_CAIXAS_PRIORITARIOS = 1
TEMPO_SIMULACO = 40
env = simpy.Environment()
env.process(rodar(env, N_CAIXAS, N_CAIXAS_PRIORITARIOS))
env.run(until = TEMPO_SIMULACO)

输出:

Cliente 1 de 37.774686064372275 anos entrou no banco às 0
Cliente 1 de 37.774686064372275 anos começou o atendimento 0
Cliente 2 de 71.29176183444024 anos entrou no banco às 1.5291101832583434
Cliente 1 de 37.774686064372275 anos terminou o atendimento 2
Cliente 2 de 71.29176183444024 anos começou o atendimento 2.2
Cliente 3 de 59.0527016599481 anos entrou no banco às 3.875677459210169
Cliente 2 de 71.29176183444024 anos terminou o atendimento 4.2
Cliente 3 de 59.0527016599481 anos começou o atendimento 4.4
Cliente 4 de 44.81820029628599 anos entrou no banco às 4.609114921062699
Cliente 5 de 29.491494333235128 anos entrou no banco às 5.517706457411619
Cliente 3 de 59.0527016599481 anos terminou o atendimento 6.4
Cliente 4 de 44.81820029628599 anos começou o atendimento 6.6000000000000005
Pausa para almoço 7.609114921062699
caixa indisponível
Cliente 5 de 29.491494333235128 anos começou o atendimento 7.609114921062699
Cliente 6 de 64.40032899103298 anos entrou no banco às 8.131823849558167
Cliente 7 de 43.83187030124143 anos entrou no banco às 8.588000648099568
Cliente 5 de 29.491494333235128 anos terminou o atendimento 9.609114921062698
Cliente 8 de 31.145934836402652 anos entrou no banco às 9.661161527123348
Cliente 6 de 64.40032899103298 anos começou o atendimento 9.809114921062697
Fim do almoço 10.609114921062698
Pausa para almoço 11.131823849558167
caixa indisponível
Cliente 7 de 43.83187030124143 anos começou o atendimento 11.131823849558167
Cliente 9 de 29.453094137468263 anos entrou no banco às 11.23535136907061
Cliente 10 de 39.6830775777505 anos entrou no banco às 11.336456179375972
Cliente 11 de 40.94774693095695 anos entrou no banco às 11.890466361540382
Cliente 7 de 43.83187030124143 anos terminou o atendimento 13.131823849558167

这里有一种方法。我将午餐嵌套在主循环中,这样进程就可以处理多个午餐中断。请注意,我确实会在午餐期间释放资源,因此在等待获取新资源时,在进程恢复之前会有一段滞后时间。

import simpy
import random
import numpy as np
class BANCO(object):
def __init__(self, env, n_caixas, n_prioritario):
self.env = env
self.caixa_prioritário = simpy.PriorityResource(env, n_prioritario)
self.quebrado = False

def tempo_quebra(self, media):
return random.expovariate(media)
def processo_caixa(env, banco, idade, id):
#Solicita um caixa
print('Cliente', id, 'de', idade, 'anos entrou no banco às', env.now)
# print('Cliente', id, 'de', idade, 'anos solicitou um caixa às', env.now)

remaining_proccess_time = 2
do_lunch = False
while remaining_proccess_time > 0:
if do_lunch:
remaining_lunch_time = 1
while remaining_lunch_time > 0:
# need this loop incase there is
# another lunch inturupt during lunch
try:
lunch_start = env.now
print('Cliente', id, 'de', idade, 'starting lunch', env.now)
yield env.timeout(remaining_lunch_time)
print('Cliente', id, 'de', idade, 'finish lunch', env.now)
remaining_lunch_time = 0
except simpy.Interrupt:
# ignore interupt and resume lunch, update remaining lunch time
print('Cliente', id, 'de', idade, 'lunch interupted', env.now)
remaining_lunch_time = remaining_lunch_time - (env.now - lunch_start)
do_lunch = False
# start processing
try:
processing_start = 0
with banco.caixa_prioritário.request() as caixa:
yield caixa

processing_start = env.now
print('Cliente', id, 'de', idade, 'anos começou o atendimento', env.now)
yield env.timeout(remaining_proccess_time)
print('Cliente', id, 'de', idade, 'anos terminou o atendimento', env.now)
remaining_proccess_time = 0
except simpy.Interrupt:
print('Cliente', id,'processing interupted for lunch',env.now)

# start lunch
do_lunch = True
# update remaing procesing time, if starte
if processing_start > 0:
remaining_proccess_time -= (env.now - processing_start)
print('Cliente', id,'caixa done',env.now)
def manutencao(env, banco, processo):
while True:
yield env.timeout(3)
if not(banco.quebrado) and processo.is_alive:
print('Pausa para almoço', env.now)
banco.quebrado = True
processo.interrupt()
yield env.timeout(3)
print('Fim do almoço', env.now)
banco.quebrado = False
def rodar(env, n_caixas, n_prioritario):
banco = BANCO(env, n_caixas, n_prioritario)
id=1
while True:
idade = np.random.triangular(20,35,90)
processo = env.process(processo_caixa(env, banco, idade, id))
# print(processo.is_alive)
env.process(manutencao(env, banco, processo))
yield env.timeout(np.random.standard_exponential())
id+=1
N_CAIXAS = 1
N_CAIXAS_PRIORITARIOS = 1
TEMPO_SIMULACO = 40
env = simpy.Environment()
env.process(rodar(env, N_CAIXAS, N_CAIXAS_PRIORITARIOS))
env.run(until = TEMPO_SIMULACO)

最新更新