def main(): filaEntrada = inicilizarEntrada('entrada.txt') processosNovos = {'tempoReal': [], 'usuario': []} processosProntos = [] processosProntosSuspenso = [] processosBloqueados = [] processosBloqueadosSuspenso = [] # Não ta sendo passado pra nenhuma função processosExecutando = [] processosFinalizados = [] so = SO() memoria = Memoria() gerenciaIO = GerenciaIO() totalProcessos = len(filaEntrada) while len(processosFinalizados) != totalProcessos: # Escalonador de longo prazo while len(filaEntrada) > 0 and filaEntrada[0].tempoChegada == so.tempoSistema: # Isso vai dar certo? if filaEntrada[0].prioridade == 0: processosNovos['tempoReal'].append(filaEntrada.pop(0)) else: processosNovos['usuario'].append(filaEntrada.pop(0)) escalona_lp(so.gerenciadorIO, processosProntos, processosProntosSuspenso, processosBloqueados, processosBloqueadosSuspenso, processosNovos, memoria) # Escalonador de médio prazo (acho que não vai ser chamado explicitamente, só indiremantente pro swap) if (len(processosProntos) == 0 and len(processosProntosSuspenso) > 0) or (len(processosBloqueados) == 0 and len(processosBloqueadosSuspenso) > 0): escalonador_mp_ativa(gerenciaIO, processosProntos,processosProntosSuspenso,processosBloqueados, processosBloqueadosSuspenso, memoria) # Escalonador de curto prazo rodadaDeEscalonadorCurto(so.tempoSistema, memoria, so.gerenciadorIO, processosBloqueados, processosProntos, processosExecutando, processosFinalizados, so.cpus) #moveBloqueadoParaExecutando(processosBloqueadosSuspenso,processosProntosSuspenso) # Espera um enter para entrar no próximo loop os.system('cls' if os.name == 'nt' else 'clear') so.imprimeSO() memoria.imprimeMemoria() imprimeFilas(processosProntos, processosProntosSuspenso, processosBloqueados, processosBloqueadosSuspenso, processosFinalizados) so.passagemDeTempo() input()
class ProcessoGerenciador: def __init__(self): print('\n\t\t\t🔵🔵🔵 Iniciando o Processo Gerenciador! 🔵🔵🔵\n') self.idProcesso = 0 self.tempo = 0 self.tempoCPU = 0 self.estadoExec = 0 self.CPU = CPU() self.estadoPronto = [] self.estadoBloqueado = [] self.tabelaProcesso = TabelaProcessos() self.memoriaPrimaria = Memoria(5) self.memoriaSecundaria = Memoria(0) self.memoriaVirtual = Memoria(0) self.tempoAlocNos = 0 self.numAlocNos = 0 self.alocFeitas = 0 self.alocNegadas = 0 # Definição da opção de escalonamento print('Como você gostaria que os processos fossem escalonados?') print('➡️ H - Escalonar por prioridade mais alta') print('➡️ X - Escalonar por número de instruções') while(True): self.modoDeEscalonamento = input('📌 Escolha uma opção: ').upper() if self.modoDeEscalonamento == 'H' or self.modoDeEscalonamento == 'X': break else: print('❌ Erro! Entrada inválida\n') print('\n') # Definição da opção de impressão print('Como você gostaria de imprimir o estado do sistema?') print('➡️ D - Impressão detalhada') print('➡️ S - Impressão simplificada') while(True): self.modoDeImpressao = input('📌 Escolha uma opção: ').upper() if self.modoDeImpressao == 'D' or self.modoDeImpressao == 'S': break else: print('❌ Erro! Entrada inválida\n') print('\n') self.criarProcessoSimulado( eProcessoInicial = True ) print('🔵Gerenciador🔵 criou um 🟡Simulado🟡') # * Método relacionado aos comandos recebidos do processo controle através do pipe def recebeComandoDoControle(self, comandoRecebido): # Comando U: Fim de uma unidade de tempo. O tempo passa quando o U é recebido. if(comandoRecebido == 'U'): self.executarProcessoSimulado() self.tempo+=1 print('\n⏰ O tempo foi incrementado. Tempo Atual: ' + str(self.tempo)) print('\n'+('-'*84)) # Comando L: Desbloqueia o primeiro processo simulado na fila bloqueada. elif(comandoRecebido == 'L'): idProcesso = self.processoBloqueadoParaPronto() variaveisDoProcesso = self.memoriaSecundaria.removerProcesso(idProcesso) inicio = time.time() memoriaTemEspaco = self.memoriaPrimaria.algoritmoWorstFit(variaveisDoProcesso) fim = time.time() self.tempoAlocNos+= (fim - inicio) self.numAlocNos+=1 if(not memoriaTemEspaco): self.memoriaPrimaria.inserirSecundariaVect(variaveisDoProcesso) print('🔵Gerenciador🔵 desbloqueou o primeiro processo da fila de bloqueados\n') # Comando I: Imprime o estado atual do sistema. elif(comandoRecebido == 'I'): print('🔵Gerenciador🔵 irá criar o 🟢Impressão🟢\n') # Pipe -> r para leitura e w para escrita rpipe, wpipe = os.pipe() idProcesso = os.fork() # Processo pai: Processo Gerenciador if idProcesso != 0: os.write(wpipe, self.modoDeImpressao.encode()) os.wait() # Espera pelo processo filho # Processo filho: Processo Impressão if idProcesso == 0: self.modoDeImpressao = os.read(rpipe, 32) self.modoDeImpressao = self.modoDeImpressao.decode() processoImpressao = ProcessoImpressao() if(self.modoDeImpressao == 'D'): processoImpressao.impressaoDetalhada(self.tabelaProcesso) elif(self.modoDeImpressao == 'S'): processoImpressao.impressaoSimplificada(self.tabelaProcesso) print('\n📗 Memória Primária ', end='') self.memoriaPrimaria.imprimeMemoria() print('📗 Memória Virtual: ', end='') self.memoriaPrimaria.imprimeMemoriaVirtual() print('📗 Memória Secundária: ', end='') self.memoriaSecundaria.imprimeTodaMemoria() print('📊 Parâmetros de Desempenho:') self.imprimeResultadosMemoria() print('\n\t\t\t🟢🟢🟢 Finalizando o Processo Impressão! 🟢🟢🟢\n') print(('-'*84)) exit() # Comando M: Imprime o tempo médio do ciclo e finaliza o sistema. elif(comandoRecebido == 'M'): # tempo médio = (soma do tempo de cpu de todos os processos não finalizados) / (todos os processos) tempoMedio = float(self.tempoCPU/self.idProcesso) print('⏰ Tempo de CPU: %.4f' % (self.tempoCPU)) print('⏰ Numero total de processos: %d' % (self.idProcesso)) print('⏰ Tempo Médio do Ciclo: %.4f' % (tempoMedio)) print('\n👋 Encerrando Sistema!') print('\n\t\t\t🔵🔵🔵 Finalizando o Processo Gerenciador! 🔵🔵🔵\n') exit() # * Funções do Processo Gerenciador: # * Função 1: Criar um novo processo simulado def criarProcessoSimulado(self, eProcessoInicial, contadorAtual=0): if eProcessoInicial: self.processoSimulado = ProcessoSimulado( idProcesso = self.idProcesso, contadorPrograma = 0, tempoInicio = 0 ) arquivo = open('init.txt', 'r') # Processo simulado inicial for instrucao in arquivo: self.processoSimulado.adicionarInstrucao(instrucao.replace("\n","")) arquivo.close() self.tabelaProcesso.adicionarProcesso(self.processoSimulado) self.inserirNaListaDeProntos(self.processoSimulado) else: processoSimulado = ProcessoSimulado( idProcesso = self.idProcesso, contadorPrograma = contadorAtual, tempoInicio = self.tempo, idPai = self.processoSimulado.idProcesso, estado = 1, # Pronto prioridade = self.processoSimulado.prioridade ) variaveisPai = deepcopy(self.memoriaPrimaria.buscarVariavelDoProcesso(self.processoSimulado.idProcesso)) for i in variaveisPai: self.alocFeitas+=1 i.idProcesso = processoSimulado.idProcesso inicio = time.time() resultadoInsercao = self.memoriaPrimaria.algoritmoWorstFit(variaveisPai) fim = time.time() self.tempoAlocNos+= (fim - inicio) self.numAlocNos+=1 if not resultadoInsercao: #self.alocNegadas+= len(variaveisPai) self.memoriaPrimaria.inserirSecundariaVect(variaveisPai) processoSimulado.instrucoes = self.processoSimulado.instrucoes.copy() self.tabelaProcesso.adicionarProcesso(processoSimulado) self.inserirNaListaDeProntos(processoSimulado) self.idProcesso += 1 # * Função 2: Substituir a imagem atual de um processo simualdo por uma nova imagem def substituirImagemProcessoAtual(self, arquivo, processoSimulado): processoSimulado.contadorPrograma = 0 processoSimulado.instrucoes = [] #processoSimulado.variaveis = {} self.memoriaPrimaria.removerProcesso(processoSimulado.idProcesso) self.memoriaSecundaria.removerProcesso(processoSimulado.idProcesso) with open(arquivo) as file: for line in file: processoSimulado.adicionarInstrucao(line.replace("\n","")) # * Função 3: Gerenciar a transição de estados do processo def inserirNaListaDeProntos(self, processoSimulado): processoSimulado.estado = 1 if processoSimulado.idProcesso in self.estadoPronto: self.estadoPronto.append(processoSimulado.idProcesso) def processoBloqueadoParaPronto(self): if len(self.estadoBloqueado) > 0: idProcesso = self.estadoBloqueado.pop(0) self.estadoPronto.append(idProcesso) self.tabelaProcesso.atualizarEstadoProcessoPorIndice( idProcesso = idProcesso, estado = 1 # Pronto ) return idProcesso def processoProntoParaBloqueado(self, processoSimulado): if len(self.estadoPronto) > 0: self.estadoBloqueado.insert(self.estadoPronto.pop(0)) processoSimulado.estado = 0 # * Função 4: Escalonar os processos def escalonadorDeProcessos(self): if(self.modoDeEscalonamento == 'H'): self.estadoPronto = self.tabelaProcesso.ordenarProcessosProntos() elif(self.modoDeEscalonamento == 'X'): self.estadoPronto = self.tabelaProcesso.ordenarNumeroInstrucoes() if self.estadoPronto == []: self.processoSimulado = None else: print('✴️ Escalonamento realizado. Proximo processo: %d' % self.estadoPronto[0]) self.processoSimulado = self.tabelaProcesso.buscarProcesso(self.estadoPronto[0]) self.CPU.quantumUsado = 0 self.trocaDeContexto(self.processoSimulado) # * Função 5: Realizar a troca de contexto def trocaDeContexto(self, processoSimulado): self.tabelaProcesso.defineProcessoEmExecucao(processoSimulado) # * Método relacionado a execução do processo simulado def executarProcessoSimulado(self): if self.processoSimulado == None and len(self.estadoPronto) > 0: self.escalonadorDeProcessos() if self.processoSimulado != None: self.CPU.executarProcesso(self.processoSimulado) self.processoSimulado = self.CPU.processoEmExecucao print('\n🟡 Executando o processo de ID: ' + str(self.processoSimulado.idProcesso)) if self.processoSimulado.instrucoes != []: self.processoSimulado.estado = 2 # Em execução print('📑 Instruções do processo atual: ', end='') for i in self.processoSimulado.instrucoes: print (i, end='; ') instrucao = self.processoSimulado.instrucoes.pop(0) print('\n📑 Instrução que será executada: '+ instrucao + ';') instrucaoDividida = instrucao.split() comando = instrucaoDividida[0] # 1. Comando N: número de variáveis que serão declaradas neste processo simulado if comando == 'N': numDeVariveis = int(instrucaoDividida[1]) self.alocFeitas+= numDeVariveis variaveisDoProcesso = [] for i in range(numDeVariveis): variavel = VariavelProcesso(self.processoSimulado.idProcesso) variaveisDoProcesso.append(variavel) inicio = time.time() memoriaTemEspaco = self.memoriaPrimaria.algoritmoWorstFit(variaveisDoProcesso) fim = time.time() self.tempoAlocNos+= (fim - inicio) self.numAlocNos+=1 if(not memoriaTemEspaco): self.memoriaPrimaria.inserirSecundariaVect(variaveisDoProcesso) # 2. Comando D: Declara uma variável inteira X, valor inicial igual a 0 elif comando == 'D': nomeVar = int(instrucaoDividida[1]) variavel = self.memoriaPrimaria.preencherVariavel(self.processoSimulado.idProcesso,nomeVar,0) # 3. Comando V: Define o valor da variável inteira x elif comando == 'V': nome = int(instrucaoDividida[1]) valor = int(instrucaoDividida[2]) variavel = self.memoriaPrimaria.mudarValor(self.processoSimulado.idProcesso,nome,valor) # 4. Comando A: Adiciona n ao valor da variável inteira x elif comando == 'A': indice = int(instrucaoDividida[1]) valor = int(instrucaoDividida[2]) variavel = self.memoriaPrimaria.buscaVariavelIndice(self.processoSimulado.idProcesso,indice) self.CPU.somaValor(variavel,valor) # 5. Comando S: Subtrai n do valor da variável inteira x elif comando == 'S': indice = int(instrucaoDividida[1]) valor = int(instrucaoDividida[2]) variavel = self.memoriaPrimaria.buscaVariavelIndice(self.processoSimulado.idProcesso,indice) self.CPU.somaValor(variavel,-valor) # 6. Comando B: Bloqueia esse processo simulado elif comando == 'B': varPrimarias = self.memoriaPrimaria.removerProcesso(self.processoSimulado.idProcesso) self.memoriaSecundaria.inserirSecundariaVect(varPrimarias) self.processoSimulado.estado = 0 # Bloqueado self.estadoBloqueado.append(self.processoSimulado.idProcesso) self.estadoPronto.remove(self.processoSimulado.idProcesso) # 7. Comando T: Termina o processo simulado elif comando == 'T': self.memoriaPrimaria.removerProcesso(self.processoSimulado.idProcesso) self.estadoPronto.remove(self.processoSimulado.idProcesso) self.tabelaProcesso.removerProcesso(self.processoSimulado) self.processoSimulado = None # 8. Comando F: Cria um novo processo simulado filho elif comando == 'F': self.criarProcessoSimulado( eProcessoInicial = False, contadorAtual = int(instrucaoDividida[1]), ) # 9. Comando R: Substitui o programa do processo pelo programa no arquivo elif comando == 'R': self.substituirImagemProcessoAtual(str(instrucaoDividida[1]), self.processoSimulado) self.tempoCPU += 1 if comando != 'T': self.processoSimulado.tempoCPU += 1 self.tabelaProcesso.atualizarProcesso(self.processoSimulado) if self.processoSimulado.instrucoes == []: # As instruções do processo foram concluídas, remover o processo self.estadoPronto.remove(self.processoSimulado.idProcesso) self.tabelaProcesso.removerProcesso(self.processoSimulado) self.processoSimulado = None self.memoriaPrimaria.removerProcesso(self.processoSimulado.idProcesso) self.passarSecundariaParaPrimaria() if self.CPU.passarQuantum() and self.processoSimulado.instrucoes != []: # Processo gastou o quantum disponível self.processoSimulado.incrementarPrioridade() self.tabelaProcesso.atualizarProcesso(self.processoSimulado) self.escalonadorDeProcessos() if comando == 'B': self.tabelaProcesso.atualizarProcesso(self.processoSimulado) self.escalonadorDeProcessos() # * Método que imprime o estado da memória def imprimeResultadosMemoria(self): # O percentual de vezes que uma requisição de alocação é negada. Neste caso o processo print("🔅 Percentual de vezes que uma requisição foi negada: %.2f" % float(100*(self.alocNegadas/self.alocFeitas))) # Tempo médio de alocação em termos de número médio de nós percorridos na alocação; print("🔅 Tempo Médio de Alocação: "+str(self.tempoAlocNos/self.numAlocNos)) # Número médio de fragmentos externos. Fragmentação externa é quando um espaço de memória # que possui espaço para alocar um processo é ignorado, e um outro é utilizado deixando um # espaço vago entre os processos na memoria. Exemplo: [x,x,w,0,z,z,a,a] print("🔅 Numero de Fragmentos Externos na Memoria Primaria: "+str(self.memoriaPrimaria.numFrag)) # * Método que passa da memória secundária para a memória primária def passarSecundariaParaPrimaria(self): if len(self.memoriaSecundaria) != 0: variaveis = self.memoriaSecundaria.removerProcesso(self.memoriaSecundaria.primeiroProcessoSec()) inicio = time.time() resultadoInsercao = self.memoriaPrimaria.algoritmoWorstFit(variaveis) fim = time.time() self.tempoAlocNos+= (fim - inicio) self.numAlocNos+=1 if not resultadoInsercao: self.alocNegadas+= len(variaveis) self.memoriaSecundaria.inserirSecundariaVect(variaveis)