Baixe o app para aproveitar ainda mais
Prévia do material em texto
Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Capítulo 4: Threads 4.2 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Introdução As threads executam dentro de uma aplicação Muitas aplicações podem ser implementadas com múltiplas threads: Editor de texto: Atualização da tela. Correção ortográfica. Ferramenta de desenho. Salvamento automático do documento. Navegador Web Recebimento dos dados. Envio de dados. Abas de navegação. Componentes de segurança. 4.3 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Introdução A criação de processos é heavy-weight enquanto a criação de thread é light-weight. Pode tornar o programa bem mais eficiente. Pode simplificar a programação. Kernels são geralmente multithreads 4.4 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Arquitetura de servidor multithread 4.5 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Benefícios Responsividade – permite continuar a execução do programa, caso uma de suas partes esteja executando uma tarefa específica Em um editor de texto, o usuário pode continuar escrevendo um texto enquanto o documento está sendo formatado. Compartilhamento de recursos – threads podem se comunicar por meio de recursos compartilhados do processo (mais fácil do que shared memory e message passing, por exemplo). Economia – criar threads é mais leve do que criar processos. Solaris: criar um processo pode ser 30 vezes mais lento do que criar uma thread. A troca de contexto pode ser 5 vezes mais lenta. Escalabilidade – pode tirar vantagem das arquiteturas multicores. 4.6 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Programação Multicore Sistemas multicore colocam pressões nos programadores: Divisão da atividade. Balanceamento da carga. Divisão dos dados. Dependência dos dados. Depuração e testes. Paralelismo: um sistema pode executar mais de uma tarefa simultaneamente. Concorrência: mais do que uma tarefa progride ao mesmo tempo por meio das trocas de contexto realizadas pelo escalonador. 4.7 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Concorrência vs. Paralelismo Execução concorrente em um único núcleo de processamento Paralelismo em um sistema multicore: 4.8 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Tipos de paralelismo: Paralelismo de dado – distribui subconjuntos de dados em diferentes processadores. A mesma operação é executa em cada conjunto. Paralelismo de tarefa – distribui threads pelos núcleos de processamento, com cada thread executando uma tarefa operação específica. Programação Multicore 4.9 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Single and Multithreaded Processes 4.10 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Single and Multithreaded Processes Fonte: Tanenbaum 4.11 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Threads de usuário e de Kernel Threads de usuário (user threads) – gerenciamento feito a nível de usuário pela biblioteca de threads. Threads de Kernel (Kernel threads) – o gerenciamento das threads é feito pelo Kernel. Geralmente, os sistemas operacionais de propósito geral suportam threads de kernel (ex. Windows, Solaris, Linux, Mac OS X) 4.12 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Threads de usuário e de Kernel Fonte: Tanenbaum O núcleo tem uma tabela de threads que acompanha todos os threads no sistema 4.13 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Threads de Kernel Quando uma thread quer criar uma nova thread ou destruir uma já existente, ela faz uma chamada ao núcleo que realiza a ação atualizando a tabela de threads. A tabela de threads do núcleo contém os registradores, o estado e outras informações de cada thread. 4.14 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Pool de threads Threads em núcleo geram um custo maior de operação do kernel quando comparadas às threads de usuário. Este custo pode ser minimizado mantedo-se um pool de threads. Fonte: https://en.wikipedia.org/wiki/Thread_pool_pattern 4.15 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Modelos multithreading One-to-One Many-to-One Many-to-Many 4.16 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Um-para-um (One-to-One) Cada thread de usuário mapeia em uma thread no kernel. Ao criar uma thread no nível de usuário, uma thread é criada no kernel. O número de threads por processo pode ser restringido devido ao overhead Exemplos: Windows Linux Solaris 9 and later 4.17 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Muitos para um (Many-to-One) Poucos sistemas suportam esse modelo: Solaria Green Threads. GNU Portable Threads. Muitas threads a nível de usuário são mapeadas em uma única thread a nível de kernel. Quando uma thread é bloqueada, todas as outras também são. Múltiplas threads não rodam em paralelo pois existe apenas uma thread por vez no kernel. 4.18 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Many-to-Many Model Permite N threads a nível de usuário serem mapeadas para N threads a nível de kernel. Exemplos: Solaris (< versão 9) Windows com ThreadFiber package 4.19 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Two-level Model Dois modelos: many-to-many com one-to-one Examples IRIX HP-UX Tru64 UNIX Solaris 8 and earlier 4.20 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Java Threads As threads em Java são gerenciadas pela JVM. Normalmente são implementadas seguindo o modelo do SO subjacente (1-to-1 ou N-to-1 ou N-to-N). 4.21 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Pthreads É uma especificação e não uma implementação. É uma API (application programming interface). existem bibliotecas que implementam Pthreads (Solaris, Linux, Mac OS X). Estudar o programa: pi_2.c Passagem de parâmetros para threads e alocação de memória no heap: thread_malloc.c thread_malloc_correto.c 4.22 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Threads implícitas: OpenMP A criação e gerência das threads são realizadas pelo compilador e pelas bibliotecas. OpenMP: é um conjunto de diretivas de compilação bem como uma API que fornece recursos para programação paralela em ambientes com memória compartilhada. Cria threads de acordo com o número de cores #pragma omp parallel for for(i=0;i<N;i++) { c[i] = a[i] + b[i]; } Programa: – openmp.c 4.23 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Semântica do fork() e exec() Se uma thread em um programa chama o fork(), o novo processo duplicará todas as threads ou o novo processo conterá apenas uma thread? – Alguns sistemas UNIX implementam as duas versões do fork(). Se uma thread chama o execve(), o novo processo irá substituir todo o processo antigo, incluindo suas threads. Se um execve() for executado após um fork(), então duplicar todas as threads se torna desnecessário. Se um execve() não for executado, então o novo processo poderá duplicar todasas threads. Programa: thread_fork.c 4.24 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Signal Handling (tratamento de sinais) Sinais são usados em Unix para notificar um processo que algum evento ocorreu. São identificados por apenas um número (sem parâmetros). Um sinal pode ser síncrono ou assíncrono, dependendo da fonte ou da razão pela qual o sinal foi gerado. – Síncrono (ex. acesso ilegal de memória e divisão por 0). • O sinal é entregue ao mesmo processo que gerou o sinal (este é o motivo de ser chamado síncrono). – Assíncrono (ex. CTRL+C para terminar um processo). • O sinal é gerado por um evento externo ao processo em execução. 4.25 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Signal Handling (tratamento de sinais) Passos: 1. Sinal é gerado pela ocorrência de algum evento. 2. O sinal é entregue ao processo. 3. O sinal é tratado pelo: 1. tratador padrão (definido pelo Kernel), ou 2. tratador definido pelo usuário. Programas: – signal01.c – signal02.c – signal03.c 4.26 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Signal Handling (tratamento de sinais) Como um sinal pode ser tratado em sistemas multithreads? Particularmente, para qual thread o sinal será entregue? – Apenas a thread que gerou o sinal. – Todas as threads do processo. – Apenas a um grupo de threads do processo. – Uma thread específica que trata todos os sinais. 4.27 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Cancelamento de threads (thread cancellation) Exemplos de cancelamento de threads: – Banco de dados: se múltiplas threads estiverem pesquisando em um banco de dados e uma delas encontrar o resultado, as threads restantes podem ser canceladas. – Quando um usuário pressiona a tecla “Stop” do navegador, todas as threads que foram criadas para o carregamento da página devem ser canceladas. Duas abordagens de cancelamento: Cancelamento assíncrono: termina a thread imediatamente (pode deixar recursos inconsistentes, exemplo: atualização de arquivo). Cancelamento adiado (deferred) a thread periodicamente verifica se existe algum pedido de cancelamento. while (1) { /* do some work for awhile */ /* . . . */ pthread testcancel(); } pthread t tid; /* create the thread */ pthread create(&tid, 0, worker, NULL); . . . /* cancel the thread */ pthread cancel(tid); 4.28 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Thread-Local Storage Thread-local storage (TLS) (armazenamento local em threads): permite cada thread ter sua própria cópia dos dados. – Diferente de variáveis locais • As variáveis locais estão visíveis apenas pelas threads invididuais. • TLS está visível em todas as chamadas da thread. Como se fosse uma variável globlal somente visível para as threads. Programa: lts.c 4.29 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Linux Threads Em Linux, não há distinção entre threads e processos. De fato, ambos são chamados de tarefas (tasks) A criação de threads é feita por meio da chamada de sistema: clone(). clone(): os parâmetros definem o que será compartilhado entre a tarefa pai e filho. Se nenhum parâmetro de compartilhamento for especificado, então clone() funciona como fork(). Quando a chamada clone() é usada, alguns ponteiros da estrutura struct task_struct do filho apontam para os mesmos elementos apontados pela tarefa pai. 4.30 Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition Linux Threads Execute o programa pi_2.c e acompanhe as chamadas de sistemas com o comando strace. Veja a chamada clone(). Silberschatz, Galvin and Gagne ©2013Operating System Concepts – 9th Edition End of Chapter 4 Slide 1 Slide 2 Slide 3 Slide 4 Slide 5 Slide 6 Slide 7 Slide 8 Slide 9 Slide 10 Slide 11 Slide 12 Slide 13 Slide 14 Slide 15 Slide 16 Slide 17 Slide 18 Slide 19 Slide 20 Slide 21 Slide 22 Slide 23 Slide 24 Slide 25 Slide 26 Slide 27 Slide 28 Slide 29 Slide 30 Slide 31
Compartilhar