











Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Encontra documentos específicos para os exames da tua universidade
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Exercicios de Sistema de Operacionais, Inclui códigos em C em Linux, chamadas de sistema em Windows e Linux
Tipologia: Exercícios
1 / 19
Esta página não é visível na pré-visualização
Não perca as partes importantes!












**Instituto de Informática - Campus São Gabriel - Curso de Sistemas de Informação Sistemas Operacionais (SO) - Professor: Paulo Amaral LISTA DE EXERCÍCIOS PRÁTICA E LABORATÓRIO 1/ Ex1: Fazer programas em e C (compilador gcc Linux/Unix) usando obrigatoriamente através parâmetros na linha de comando p e utilizando na versão final dos programas em C somente funções de biblioteca de E/S (stdio) do C (como printf, scanf, etc.), não utilize nenhum método de C++ como cin e cout, com as seguintes especificações :
Pesquisar em um intervalo fechado de números inteiros [MIN ... MAX] , ou seja, delimitado pelos valores inteiros MIN e MAX recebidos obrigatoriamente através parâmetros na linha de comando (C), e imprimir os números que são simultaneamente ímpar, múltiplo de 7 e não múltiplo de
Exemplo (com: MIN = 2 e MAX = 10): ENTRADA: ./intervalo.exe 2 10 SAÍDA: 7**
Implementar uma calculadora com as quatro operações aritméticas básicas (+, -, x e / ). Os operandos e o operador são recebidos obrigatoriamente através parâmetros na linha de comando (shell script e C). Exemplo: ENTRADA: ./calcl.exe 2 x 3 SAÍDA: 2 x 3 = 6
#!/bin/bash if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then echo "Entre dois numeros e um operador" echo "Exemplo: ./cal 2 + 2" exit 0 fi array[0]=$1 # Primeiro operando array[1]=$2 # Operador aritmetico array[2]=$3 # Segundo operando if [ "${array[1]}" == "+" ]; then echo "Resultado da Adição:" expr ${array[0]} + ${array[2]} fi if [ "${array[1]}" == "-" ]; then echo "Resultado da Subtração:" expr ${array[0]} - ${array[2]} fi if [ "${array[1]}" == "/" ]; then echo "Resultado da divisao:" expr ${array[0]} / ${array[2]} fi if [ "${array[1]}" == "*" ]; then echo "Resultado da Multiplicação:" expr "${array[0]}" * "${array[2]}" fi
Ide: Esse diretório carrega informações sobre dispositivos IDE no seu sistema, cada canal IDE é representado por um diretório separado, assim como para /proc/ide/ide0 e /proc/ide/ide1. Interrupts: esse arquivo contem os registros do numeros de interrupções por IRQ na arquitetura x86. Iomem: esse arquivo mostra um mapa corrente do sistema de memória para cada dispositivo físico. Ioports: o arquivo de saida produz uma lista corrente de regiões de portas registradas para uso de comunicação I/O com algum dispositivo. Irq: Este diretório é usado para configurar IRQS para CPU, que permite sistemas conectem a uma irq particular para somente um CPU. Cada IRQ tem sem próprio diretório, permitindo configuração individual para cada IRQ. Kcore: esse arquivo representa a memoria fisica do sistema, e grava arquivos no formato core. Locks: este arquivo mostra os os arquivos correntes liberados pelo kernel. O conteúdo desse arquivo contem um kernel interno de debug de dados e pode variar , dependendo do uso do sistemas. Misc: esse arquivo lista drivers registrados em miscellaneous Partitions : Most of the information here is of little importance to the user, except for the following columns:
processor : 0 vendor_id : GenuineIntel cpu family : 15 model : 1 model name : Intel(R) Pentium(R) 4 CPU 1.70GHz stepping : 2 cpu MHz : 1715. cache size : 256 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm up bogomips : 3433. Tabela de Interrupções (cat /proc/interrupts) CPU 0: 964773 XT-PIC timer 1: 573 XT-PIC i 2: 0 XT-PIC cascade 5 : 0 XT-PIC SI 6 : 5 XT-PIC floppy 7 : 1 XT-PIC parport 8 : 1 XT-PIC rtc 9 : 1 XT-PIC acpi 10 : 0 XT-PIC ehci_hcd:usb4, eth 11 : 2632 XT-PIC ohci_hcd:usb1, ohci_hcd:usb2, ohci_hcd:usb3, eth 12 : 8247 XT-PIC i 14 : 20249 XT-PIC ide 15 : 68022 XT-PIC ide NMI: 0 LOC 964746 ERR: 0 MIS Tabela de Endereços de portas (cat /proc/ioports) 0000-001f Dma 0020-0021 pic 0040-0043 timer 0050-0053 timer
HighTotal 0 kB HighFree 0 kB LowTotal 386872 kB LowFree 25424 kB SwapTotal 819272 kB SwapFree 819272 kB Dirty 0 kB Writeback 0 kB AnonPages 110384 kB Mapped 42996 kB Slab 68760 kB PageTables 1384 kB NFS_Unstable 0 kB Bounce 0 kB CommitLimit 1012708 kB Committed_AS 308692 kB VmallocTotal 638968 kB VmallocUsed 2652 kB VmallocChunk 635996 kB
Usando um computador de laboratórios ou um computador pessoal de um componente do grupo com o sistema operacional Windows. Fazer tabelas contendo os vetores de interrupção de hardware, o endereço das portas de E/S e o mapa de memória. O Computador do grupo deve ser especificado (hardware e software).Dica : Iniciar-programas - acessórios - ferramentas de sistema – informações de sistema. Ex 3: 3.1 Descreva (justificando) o que acontece com as sequências de comandos a seguir:
Tipos de Chamadas de sistemas para Processos no Linux Na maioria dos casos não é necessário invocar chamadas de sistemas diretamente, mas podem haver situações onde a biblioteca padrão não implementa uma boa função para você. Neste caso o programador deve manualmente invocar uma chamada de sistema, usando qualquer uma das macros do de chamadas de sistema ou a função syscall(). Exemplo: #include <linux/unistd.h> A _syscall macro Chamada de sistema desejada Configuração: é importante saber que chamadas de sistema é um protótipo.Você precisa saber como sobre muitos argumentos, relativos a seus tipos e as funções de retorno do tipo. Existem seis macros de chamadas de sistemas que pode fazer chamadas para um sistema facilmente. Uma das formas: _syscallX(type,name,type1,arg1,type2,arg2,...)
a que ela pertence. Um objeto processo recebe na sua criação, uma prioridade que varia de zero a quinze e cada thread recebe uma prioridade variando de duas unidades para cima ou para baixo da prioridade do processo. O critério usado para variar a prioridade de uma thread é o tempo de uso do processador. Se a thread é interrompida por usar todo o quantum de tempo que lhe foi atribuído, o escalonador do Windows 2000 reduz sua prioridade, caso contrário sua prioridade é aumentada. Tipos de chamadas mais utilizadas em Sistemas Operacionais Linux e Windows _access(2) - verifica se o processo tem permissão para leitura, escrita ou execução de um arquivo acct(2) - muda o processo de contabilidade para ligado ou desligado alarm(2) - define um alarme de relógio para envio de um sinal chdir(2) - muda o diretório de trabalho close(2) - encerra um descritor de arquivo creat(2) - abre e cria arquivos e/ou dispositivos exec(2) - executa um arquivo execve(2) - executa programa _exit(2) - termina o processo atual fork1(2) - cria um novo processo fork(2) - cria um processo filho getpid(2) - pega a identificação do processo getppid(2) - obtém a identidade do processo. Retorna a ID do processo pai do processo atual kill(2) - envia um sinal específico para um determinado processo link(2) - renomeia um arquivo _lwp_cond_signal(2) - sinal para comunicação entre threads ou LWP _lwp_cond_wait(2) - threads esperando a ocorrência de um evento _lwp_create(2) - cria uma nova thread _lwp_kill(2) - envia um sinal para uma thread _lwp_mutex_lock(2) - realiza exclusão mutua de uma thread _lwp_self(2) - identifica uma thread lwp_wait(2) - espera pelo término de uma thread mkdir(2) - cria diretórios nice(2) - muda prioridade de um processo open(2) - abre e possibilita a criação de arquivos ou dispositivos pause(2) - aguarda por um sinal pipe(2) - cria um canal de interprocessos pset_assign(2) - constrói conjuntos de processos read(2) - leitura de arquivo rmdir(2) - remove diretórios vazios semctl(2) - realiza operações de controle de semáforos semop(2) - realiza operações de semáforos shmat(2) - operações de memória particionada shmctl(2) - controle de memória compartilhada sigsend(2) - envia sinal para um processo ou grupo de processos ulimit(2) - pega e seleciona limites de processo uname(2) - exibe informações do sistema vfork(2) - cria um processo filho e bloqueia o processo pai wait(2) - espera o processo filho terminar waitid(2) - espera um processo filho para mudança de estado waitpid(2) - espera pelo término de um processo write(2) - envia uma mensagem para outro usuário
chrroot – executa o comando ou Shell interativo com diretório raiz especial. Chamadas de sistemas Operacionais Win CreateProcess - Cria um novo processo CreateThread - Cria um novo thread em um processo existente CreateFiber - Cria um novo filamento ExitProcess - Termina o processo atual e todos os seus threads ExitThread - Termina este thread ExitFiber - Termina este filamento SetPriorityClass - Define a classe de prioridade para um processo SetThreadPriority - Define a prioridade de um thread CreateSemaphore - Cria um novo semáforo CreateMutex - Cria um novo mutex OpenSemaphore - Abre um semáforo existente openMutex - Abre um mutex existente WaitForSingleObject - Bloqueia em um único semáforo, mutex. WaitForMultipleObjects - Bloqueia em um conjunto de objetos cujos manipuladores são dados PulseEvent - Torna um evento sinalizado e depois não sinalizado ReleaseMutex - Libera um mutex para permitir que outro thread o adquira RealeseSemaphore - Incrementa o contador do semáforo EnterCriticalSection - Adquire um impedimento em uma seção crítica LeaveCriticalSection - Libera o impedimento em uma seção crítica Ex 4: Edite, compile e rode (no gcc/Linux) os programas fork1.c e fork2.c (mostrados a seguir), escreva e explique (justificando) cada linha que será impressa na tela 4. //ALUNOS: RODRIGO FARIA TAVARES // MARCELO VIEIRA // SHAWYSON SALVIO GOMES DE ALMEIDA // ROBERTA MARIANA EMILIANO DE ALMEIDA /* programa fork1.c - ref SOC - SGG-CAMPUS pg 71 / #include <stdio.h> / para printf / #include <unistd.h> / para fork, getpid, wait e exit / #include <sys/types.h> / para fork, getpid, wait e exit / int main(int argc, char * argv[]) { int x; //variável receberá o número do processo criado x = fork(); / cria processo / if(x<0) { / ocorreu erro / se o processo for menor que zero fprintf(stderr,"fork falhou"); //função(stderr) envia mensagem para a tela exit(-1); //fecha o programa pois não retornou Zero } else if(x==0){ / codigo do filho */ printf("\nPID = %d :\n\n",getpid()); //getpid() obtém o No do processo //e o imprime em tela.
Considere que PID = 1000 + NMAT%20 e que o sistema operacional cria um processo com número de identificação PID para executar o programa provaso.exe e que os processos criados pelo programa provaso.exe recebem números de identificação de processo seqüenciais: PID + 1, PID + 2, PID + 3, etc. Escreva o que será impresso pelo programa na tela, os valores assumidos por todas as variáveis (nos comandos nos quais elas são referenciadas) e todos os cálculos necessários (somente a resposta não será considerada). //ALUNOS: RODRIGO FARIA TAVARES // MARCELO VIEIRA // SHAWYSON SALVIO GOMES DE ALMEIDA // ROBERTA MARIANA EMILIANO DE ALMEIDA /* programa provaso.c - ref SOC - SGG-CAMPUS pg 71 / #include <stdio.h> / para printf / #include <unistd.h> / para fork, getpid, wait e exit / #include <sys/types.h> / para fork, getpid, wait e exit / int main(int argc, char * argv[]) { int i, j, k, p; //variaveis for (i = 1 ; i < argc; i++) //ficara em loop enquanto tiver existirem parametros { //argc tera o valor da qtde de parametros passados //por convencao o p que recebe o processo a ser criado tem o valor igual a //zero. Por isso quando executa o programa o p sempre esta igual a zero //pois é um processo filho. é a maneira do SO diferenciar o que é filho. p = fork(); / cria processo / if(p < 0) { / ocorreu erro / fprintf(stderr,"fork falhou");//funcao que imprime a string se der erro. exit(-1); //finaliza o programa caso de erro, nao retorne zero } //por convensao do SO, todo processo filho recebe 0, por isso p = 0. else if(p==0) //p = 0 pois eh status do filho { / codigo do filho / printf("\n p = %d PID = %d : %s \n", p, getpid(), argv[i]); //imprime a linha referente exit(0);//termina ok //ao status/PID filho/parametro } //passado. else { / codigo do pai */ wait(NULL );//suspende a execucao ate a morte do filho printf("\ni = %d p = %d PID = %d\n",i, p, getpid()); //imprime o indice do loop, o PID do
//filho, o PID Pai que originou o pro- }//for //cesso filho. Como recursao. exit(0); /* termina ok */ } Ex 6: Edite, compile e rode (no gcc/Linux) o programa (fork3.c ) com as seguintes especificações:
Ex 8: Faça um programa usando threads, semáforos ou monitores que resolva um dos seguintes problemas:
**- Filósofos comedores,
void levanta_da_cadeira(CLIENTE *ficha_do_cliente); int main(int argc, char * argv[]) { int i; if(argc > 1) { for(i = 0; i < 8; printf("\n"), i++); //espaco na tela printf("\n\nDEBORA BRUMER!\n"); printf("RODRIGO FARIA\n"); printf("MARCELO VIEIRA\n"); printf("ROBERTA\n"); printf("\nPROGRAMA: Barbeiro Dorminhoco.\n"); printf("Simulacao do barbeiro dorminhoco.\n"); printf("Entrada: executar ./exer8\n"); printf("Saida..: Exibira o dia do barbeiro dorminhoco\n"); for(i = 0; i < 8; printf("\n"), i++); //espaco na tela } else { pthread_t threads[NUM_CLIENTES+1]; unsigned i; pthread_create(&threads[0], NULL, thread_barbeiro, NULL); for(i=0; i<NUM_CLIENTES; i++) { cliente[i].id = i; cliente[i].nome = nomes[i]; cliente[i].tamanho_do_cabelo = 1000; pthread_create(&threads[i+1], NULL, thread_cliente, (void *)&cliente[i]); } for (i=0; i<(NUM_CLIENTES+1); i++) pthread_join(threads[i], NULL); pthread_mutex_destroy(&barbearia_mutex); pthread_cond_destroy(&cliente_corta_cond); pthread_cond_destroy(&cliente_espera_cond); pthread_exit(NULL); }//else } //======================================================================= ============= void *thread_barbeiro(void *param) { while ((numero_de_cortes <= CORTESMAX ) || (numero_de_clientes != 0)) {
void *thread_cliente(void *fc) { CLIENTE *ficha_cliente; ficha_cliente = (CLIENTE )fc; while(barbearia_aberta == TRUE) { pega_senha(ficha_cliente); usleep(ficha_cliente->tamanho_do_cabelo100); } pthread_exit(NULL); } //======================================================================= ================ BOOL pega_senha(CLIENTE *ficha_do_cliente) { BOOL retorno=FALSE; pthread_mutex_lock(&barbearia_mutex); printf("Sistema: %s entra na barbearia.\n", ficha_do_cliente-
nome); if(numero_de_clientes < NUM_CADEIRAS) { numero_de_clientes++; printf("Sistema: %s aguarda para o corte.\n", ficha_do_cliente- nome); pthread_cond_signal(&barbeiro_cond); pthread_cond_wait(&cliente_espera_cond, &barbearia_mutex); printf("%s: Minha vez.\n", ficha_do_cliente->nome); pthread_cond_wait(&cliente_corta_cond, &barbearia_mutex); } else { printf("%s: Barbearia cheia! Voltarei mais tarde.\n", ficha_do_cliente->nome); } pthread_mutex_unlock(&barbearia_mutex); return retorno; }//fim main