Universidade Estadual de Mato Grosso do Sul – UEMS Curso de Licenciatura em Computação Sistemas Operacionais Threads Prof. José Gonçalves Dias Neto [email protected] Ambiente Monothread Em um ambiente Monothread um processo suporta apenas um programa em seu espaço de endereçamento. Assim ambientes concorrentes são programados através de múltiplos processo e subprocessos. Uma aplicação pode ser divida em diversos processos separados. Esta implementação consome diversos recursos do sistema (tempo de CPU para alocar/desalocar). Por estarem em processos diferentes com espaços de endereçamento diferentes, a comunicação entre processos é lenta e complexa. Ambiente Monothread Ambiente Monothread. Cada processo suporta unicamente um thread. Ambiente Multithread Não existe a ideia de programa associado a processo, mas sim associado a thread. Cada processo tem pelo menos um thread e compartilha seu espaço de endereçamento com as threads contidas no processo. Um thread pode ser definido como um fluxo de um programa que é executado concorrentemente ao programa principal. ? Vantagem: Diminuição do overhead de criação, troca e eliminação de processos. ? Ambiente Multithread Threads compartilham processador e têm as mesmas trocas de estados que um processo. Cada thread possui seu próprio contexto de hardware. Dentro de um processo, todas as threads deste compartilhas o espaço de endereçamento e contexto de software. Threads são implementadas através do Bloco de Controle de Threads (TCB – Thread Control Block). O processo torna-se a unidade de alocação e os threads unidades de escalonamento. Ambiente Multithread Ambiente Multithread Programas com múltiplos threads são mais rápidos do que os implementados com múltiplos processos. Não existe proteção no acesso a memória por threads do mesmo processo. Em ambientes multithreads, um thread pode solicitar um serviço remoto enquanto a aplicação realiza outras tarefas sem ficar bloqueada. Em quantidades grandes de threads/processo, pode acorrer overhead. Ambiente Multithread Arquitetura Multithread Para se beneficiar da arquitetura Multithread, a aplicação deve garantir que partes diferentes do seu código sejam executadas concorrentemente. Threads podem ser oferecidas na forma: Modo Usuário (fora do Kernel) Modo Kernel Modo Híbrido. Arquitetura Multithread Threads em Modo Usuário - TMU São implementadas pela aplicação e não pelo Sistema Operacional. Necessita de uma biblioteca para gerenciar as threads. (criar/destruir/escalonar). O SO não sabe da existência da thread. Vantagem de poder utilizar thread mesmo em SO que não dão suporte. Não permite que múltiplos threads de um mesmo processo rodem paralelamente em múltiplas CPUs. O sistema seleciona apenas processos e não threads. Threads em Modo Kernel - TMK São implementadas diretamente pelo kernel do SO. O SO pode escaloná-las individualmente. Os threads de um mesmo processo podem ser escalonados para rodar concorrentemente. Baixo desempenho devido a várias alternâncias entre estados (modo usuário para modo kernel). Threads Modo usuário e modo Kernel Threads em Modo Híbrido Une as vantagens dos modos usuário e Kernel. Infelizmente também herda seus problemas. O programador desenvolve a aplicação em termos de TMU e especifica quantos TMK são associados ao processo. Os TMU são mapeados em TMK enquanto o processo está sendo executado. Quanto um TMK recebe uma chamada bloqueante, todos os TMU mapeados nele serão bloqueados. Threads em Modo Híbrido Utilização de Arquitetura de Threads Modo Usuário: Compaq Open VMS 6 Modo Kernel: Windows 2000, Unix, Linux, OpenVMS 7 Modo Híbrido: Sun Solaris. POSIX Threads - PThreads A criação de Threads e Unix e derivados, dentre eles o Linux, pode ser feita através da biblioteca Pthreads. PThreads podem implementar threads em nível de usuário, em nível de kernel ou híbrido. Inclusão do header padrão da biblioteca Pthreads #include <pthread.h> POSIX Threads - PThreads Funções básicas para criação e gerência Pthreads: pthread_create(); pthread_exit(); pthread_join(); pthread_yield(); pthread_attr_init(); ptrhead_attr_destroy();