Prévia do material em texto
UNIVERSIDADE VEIGA DE ALMEIDA Superior de tecnologia em análise e desenvolvimento de sistemas – EAD AMANDA SANTANA RIBEIRO CARDOSO Matrícula: 1240120391 Disciplina: Sistemas Operacionais Tutor: André Luiz Braga Alocação de recursos Rio de Janeiro – Brasil 2024 Algoritmo "concorrentes" Var // Variaveis de controle das threads thread thread_A, thread_B, thread_C: thread; // Semaforos de controle sema_impressora, sema_plotter, sema_scanner: semaforo; Procedimento Proc_A() Início Enquanto (verdadeiro) Faça // Procedimento nunca termina processa_algo(); aloca_plotter(); processa_algo_utilizando_plotter(); libera_plotter(); Fim Enquanto; Fim; Procedimento Proc_B() Início Enquanto (verdadeiro) Faça // Procedimento nunca termina processa_algo(); aloca_scanner(); processa_algo_utilizando_scanner(); aloca_impressora(); processa_algo_utilizando_scanner_impressora(); aloca_plotter(); processa_algo_utilizando_scanner_impressora_plotter(); libera_plotter(); libera_impressora(); libera_scanner(); Fim Enquanto; Fim; Procedimento Proc_C() Início Enquanto (verdadeiro) Faça // Procedimento nunca termina processa_algo(); aloca_impressora(); processa_algo_utilizando_impressora(); aloca_scanner(); processa_algo_utilizando_scanner_impressora(); libera_impressora(); libera_scanner(); Fim Enquanto; Fim; Início sema_impressora = 1; // Inicia semaforo de controle da impressora sema_plotter = 1; // Inicia semaforo de controle do plotter sema_scanner = 1; // Inicia semaforo de controle do scanner // Inicia as threads colocando-as em execução paralelamente pthread_create(thread_A, Proc_A); // Inicia Proc_A como uma thread pthread_create(thread_B, Proc_B); // Inicia Proc_A como uma thread pthread_create(thread_C, Proc_C); // Inicia Proc_A como uma thread // faz com que a thread principal espere as demais acabarem pthread_join(thread_A); pthread_join(thread_B); pthread_join(thread_C); Fim. 1. “0pthread_join(thread_A);, pthread_join(thread_B);, pthread_join(thread_C);” : As threads são projetadas para rodar indefinidamente, o que significa que pthread_join nunca será concluído. Isso pode causar um bloqueio na execução do programa. Dentro dos procedimentos Proc_A, Proc_B, e Proc_C: aloca_scanner();, aloca_impressora();, aloca_plotter(); em diferentes ordens entre as threads. Um possível deadlock pode ocorrer, já que as threads podem tentar alocar os mesmos recursos em diferentes sequências Ausência de validação para a liberação de semáforos em: libera_plotter();, libera_impressora();, libera_scanner(); Se uma thread falhar ou for encerrada inesperadamente, os semáforos podem permanecer bloqueados, impedindo outras threads de prosseguirem. Linhas que podem causar condição de corrida: • processa_algo_utilizando_plotter(); • processa_algo_utilizando_scanner(); • processa_algo_utilizando_scanner_impressora(); • processa_algo_utilizando_scanner_impressora_plotter() As operações nesses métodos presumem que o recurso foi corretamente alocado antes do uso, mas o programa não impede que outra thread interfira, resultando em inconsistências no estado do recurso. 3. Para corrigir os problemas identificados no algoritmo e garantir sua execução sem erros, é necessário realizar ajustes nas estruturas de sincronização, eliminar possíveis deadlocks e evitar bloqueios indefinidos. Podemos modificar a Inicialização dos Semáforos, como: • Substituir a inicialização manual sema_impressora = 1; etc., por uma API de semáforos padrão, como sem_init ( Isso garante que os semáforos sejam configurados corretamente e fiquem prontos para uso em ambientes multithread.) • Adicionar Controle para Evitar Deadlocks, podendo implementar uma lógica para garantir que os recursos sejam adquiridos na mesma ordem por todas as threads, eliminando a possibilidade de deadlocks e garantindo a mesma sequência de alocação de recursos em todas as outras threads • Adicionar Verificações nos Métodos de Liberação: então antes de liberar um recurso, verificar se ele foi alocado pela thread atual. Podendo também implementar um controle com flags (ou estados locais por thread) e adotar essa lógica para todos os outros recurso • Como os loops são infinitos e pthread_join nunca será concluído, introduza uma variável global de controle (executando) para permitir uma finalização ordenada e no final do programa, defina executando = falso; e sinalize para as threads finalizarem. Use pthread_join apenas após garantir que os loops foram encerrados.