Baixe o app para aproveitar ainda mais
Prévia do material em texto
ATIVIDADE INDIVIDUAL AVALIATIVA CURSO: DISCIPLINA: Engenharia e Ciência da Computação Sistemas Operacionais 1a Atividade: (Valor 3,0 pontos; Competência: Síntese – 15 linhas; Ref.: Enade 2008) A falta de uso do parágrafo na resposta implica na perda de 10% do valor da questão. A falta de uso correto de pontuações e vírgulas, quando se aplicarem, implica na perda de 10% do valor da questão. A falta de uso dos mesmos índices do enunciado e a falta da mesma quantidade de itens na resposta, implicam na perda de pelo menos 10% da questão. A tabela abaixo relaciona e compara os tempos de latência de duas operações, em um sistema operacional Unix sob uma arquitetura monoprocessada, implementadas de 3 formas diferentes: por threads a nível de usuário (implementadas pela aplicação), por threads a nível de núcleo (escalonamento e chaveamento pelo núcleo), e por meio de processos (TANENBAUM, Sistemas Operacionais, 4ª Ed, Capitulo 2). Operação Threads: nível usuário (µs) Threads: nível núcleo (µs) Processos (µs) Fork nulo 34 948 11.300 Signal-wait 37 441 1.840 Em função dos dados apresentados na tabela acima: a) Explique os prováveis motivos que embasam as diferenças de tempo de latência observadas. b) Elabore um programa em qualquer linguagem de programação que evidencie a concorrência entre três instâncias de uma thread cujo objetivo é apenas imprimir seu identificador (ID). Respostas: A) Um processo é um programa individual que está em execução, cada processo é representado no SO(Sistema Operacional) por estruturas de controle, ele controla os valores atuais dos registradores da CPU. Eles praticamente disputam a atenção da CPU, que só permite um processo por vez, é uma única trilha de execução, e executa sobre um espaço de endereçamento próprio, um único processo pode estar no estado “running” num dado processador, num dado estante. Cada processo tem seu registrador lógico, sempre criados via “system call”, no UNIX chamado de fork, quando criado um processo filho tem seu próprio espaço de endereçamento. O fork vai abrindo outros processos, e assim por diante, como ele não tem threds todos os processos criados por ele ficam aguardando o espaço da CPU, eles geram muitos deles até finalizar o processo inicial. As threads permitem paralelismo em um programa de aplicação, sendo assim múltiplas atividades podem executadas de forma simultânea. Elas possuem sua própria pilha de execução, cada roda um código sequencial, definido do programa de aplicação no qual foram definidas, sendo assim elas compartilham o mesmo espaço de endereçamento do processo ao qual pertencem. Uma aplicação em múltiplas threads sequenciais são executadas em paralelo, assim o modelo de programação torna-se mais simples. Pois são muito mais leves que os processos. Threads usuário: Será criada por um conjunto de rotinas de biblioteca, implementa os procedimentos de gerenciamento de threads. Eles incluem a possibilidade de criar, destruir e bloquear algoritmos de escalonamento. O núcleo do sistema não reconhece as threads , ele executa o escalonamento pesado no qual as threads foram definidas. Sendo assim o tempo de processamento é distribuído pelo escalonador de threads da biblioteca. Threads núcleo: são criadas pelo núcleo do sistema operacional. Assim, a cada manipulação primitiva de threads corresponde uma rotina de biblioteca, que por sua vez empacota os parâmetros da chamada e executa uma troca de contexto, passando a execução para o núcleo que mantem as informações de contexto sobre threads e processos pesados. Desta forma, as operações das threads são realizadas pelo sistema operacional. A cada thread no programa de aplicação corresponderá uma thread no núcleo. Mas o chaveamento das threads dentro do mesmo processo pesado, envolve o núcleo o que representa um impacto significativo e considerável no desempenho do sistema como um todo. B) Código em Visualg (para melhor entendimento da situação em palavras) exemplificando a concorrência de uma thread. Algoritmo "simulaçao de disputa da thread" Var // Seção de Declarações das variáveis randon: vetor[0..2] de inteiro inst1, inst2, inst3: inteiro i: inteiro Inicio // Seção de Comandos, procedimento, funções, operadores, etc... i <- 1 enquanto i < 20 faca randon[0] <- 1 randon[1] <- 2 randon[2] <- 3 inst1 <- Randi (3) inst2 <- Randi (3) inst3 <- Randi (3) escreval (randon[inst1]) escreval (randon[inst2]) escreval (randon[inst3]) i <- i+1 fimenquanto fimalgoritmo 2a Atividade: (Valor 2,0 pontos; Competência: Compreensão; Ref: Enade 2008) A máquina acima ilustra os estados em que um processo pode se encontrar durante o seu ciclo de vida. Elabore um programa em qualquer linguagem de programação que simule o funcionamento desta máquina, incluindo as circunstâncias em que ocorrem as transições (TANENBAUM, Sistemas Operacionais, 4ª Ed, Capitulo 1). Código : #include <stdio.h> #define RUNNING 1 #define BLOCKED 2 #define READY 3 void print_status(int status) { if (status == RUNNING) { printf("Estado: Running\n"); } else if (status == READY) { printf("Estado: Ready\n"); } else if (status == BLOCKED) { printf("Estado: Blocked\n"); } } int main() { int curr_status = RUNNING; while(true) { print_status(curr_status); int next_status; printf("\nDigite a proxima mudanca de estado: "); scanf("%d", &next_status); if (curr_status == RUNNING) { if (next_status==1) { curr_status=BLOCKED; } else if (next_status==2) { curr_status=READY; } else { printf ("\nNão é possivel"); } } else if (curr_status == BLOCKED) { if (next_status==4) { curr_status=READY; } else { printf ("\nNão é possivel"); } } else if (curr_status == READY) { if (next_status==3) { curr_status=RUNNING; } else { printf ("\nNão é possivel"); } } } return 0; }
Compartilhar