Interrupções de processos
Você está todo feliz e contente atravessando a galáxia no seu X-Wing quando... PIMBA! Seu dróide astromecânico pifa e só lhe resta interromper a viagem para consertá-lo, antes que apareça um maldito caça TIE das forças imperiais.
Nesta seção iremos interromper processos já em execução e depois retomar a operação inicial. A aplicação mais óbvia é para a quebra de equipamentos durante a operação, como no caso do R2D2.
A interrupção de um processo em SimPy é realizada por meio de um comando Interrupt
aplicado ao processo já iniciado. O cuidado aqui é que quando um recurso é interrompido por outro processo ele causa uma interrupção, de fato, no Python, o que nos permite utilizar o bloco de controle de interrupçãotry:...except
, o que não deixa de ser uma boa coisa, dada a sua facilidade.
Criando quebras de equipamento
Voltando ao exemplo do X-Wing, considere que a cada 10 horas o R2D2 interrompe a viagem para uma manutenção de 5 horas e que a viagem toda levaria (sem não houvessem paralisações) 50 horas.
Inicialmente, vamos criar duas variáveis globais: uma para representar se o X-Wing está operando - afinal, não queremos interrompê-lo quando ele já estiver em manutenção - e outra para armazenar o tempo ainda restante para a viagem.
O próximo passo, é criar uma função que represente a viagem do x-wing, garantindo não só que ela dure o tempo correto, mas também que lide com o processo de interrupção:
O importante no programa anterior é notar o bloco try:...except:,
interno ao laço while duracaoViagem > 0,
que mantém o nosso X-Wing em processo enquanto a variável duracaoViagem
for maior que zero. O except
aguarda um novo comando, o simpy.Interrupt
, que nada mais é do que uma interrupção causada por algum outro processo dentro do Environment.
Quando executado, o programa fornece uma viagem tranquila:
A viagem é tranquila, pois não criamos ainda um "gerador de interrupções", que nada mais é do que um processo em SimPy que cria a interrupção da viagem.
Note, na penúltima linha do código anterior, que o processo em execução foi armazenado na variável viagem
e oque devemos fazer é interrompê-lo de 10 em 10 horas. Para tanto, a função paradaTecnica
a seguir, verifica se o processo de viagem está em andamento e paralisa a operação depois de 10 horas:
A função paradaTecnica,
portanto, recebe como parâmetro o próprio objeto que representa o processo viagem
e, por meio do comando:
Provoca uma interrupção no processo, a ser reconhecida pela função viagem
na linha:
Adicionalmente, o processo parada técnica também deve ser inciado ao início da simulação, de modo que a parte final do modelo fica:
Quando executado, o modelo completo fornece como saída:
Alguns aspectos importantes do código anterior:
A utilização de variáveis globais foi fundamental para informar ao processo de parada o status do processo de viagem. É por meio de variáveis globais que um processo "sabe" o que está ocorrendo no outro;
Como a execução
env.run()
não tem um tempo final pré-estabelecido, a execução dos processos é terminada quando o laço:Torna-se falso. Note que esse
while
deve existir nos dois processos em execução, caso contrário, o programa seria executado indefinidamente;Dentro da função
paradaTecnica
a variável globalviajando
impede que ocorram duas quebras ao mesmo tempo. Naturalmente o leitor atento sabe que isso jamais ocorreria, afinal, o tempo de duração da quebra é inferior ao intervalo entre quebras. Mas fica o exercício: execute o mesmo programa, agora para uma duração de quebra de 15 horas e veja o que acontece.Se um modelo possui uma lógica de interrupção
.interrupt()
e não possui um comandoexcept simpy.Interrupt
para lidar com a paralização do processo, o SimPy finalizará a simulação retornando o erro:Na próxima seção é apresentada uma alternativa para manter o processamento da simulação.
Last updated