aula04 processos thread

38
IFTO-Palmas Prof. Helder 1 SISTEMAS OPERACIONAIS AULA - 4 Threads Instituto Federal do Tocantins – Campus Palmas Prof. Helder Cleber A. Pereira 2011

Upload: estacaovirtual2011

Post on 12-Aug-2015

93 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 1

SISTEMAS OPERACIONAIS

AULA - 4Threads

Instituto Federal do Tocantins – Campus PalmasProf. Helder Cleber A. Pereira

2011

Page 2: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 2

SISTEMAS OPERACIONAIS

Definições de threads

Page 3: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 3

Definições de threads

Uma thread é basicamente uma linha de execução independente, contida dentro de um processo. Ou seja, threads permitem que um processo “faça várias coisas de forma simultânea” já que um processo pode ter várias threads;

Todas as threads que fazem parte de um mesmo processo compartilham praticamente os mesmos recursos, portanto, todas tem acesso as variáveis globais;

Em sistemas operacionais tradicionais, cada processo tem um espaço de endereçamento e uma única thread de controle;

A funcionalidade de múltiplas threads quase se sobrepõe a definição de múltiplos processos com fork(). Contudo, frequentemente existem situações onde é desejável ter múltiplas threads de controle no mesmo espaço de endereçamento executando quase em paralelo, como se eles fossem processos separados;

Page 4: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 4

SISTEMAS OPERACIONAIS

Uso de threads

Page 5: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 5

Uso de threads

Comparado com a definição de processo, podemos chamar as threads de miniprocessos;

A principal razão para existirem threads é que em muitas aplicações ocorrem múltiplas atividades ao mesmo tempo. Algumas dessas atividades podem ser bloqueadas de tempos em tempos;

O modelo de programação se torna mais simples se decompormos uma aplicação em múltiplas threads sequenciais que executam quase em paralelo;

Tanto os processos como as threads promovem a capacidade de processamento paralelo. As threads adicionam um novo elemento: a capacidade de entidades paralelas compartilharem o mesmo espaço de endereçamento, consequentemente, as variáveis globais;

Page 6: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 6

Uso de threads

processo

thread

Figura 1 – Figura representativa de um processo e de uma thread

Page 7: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 7

Uso de threads

Um segundo argumento para a existência de threads é que eles são mais fáceis (rápidos) de criar e destruir que os processos, pois não têm quaisquer recursos associados a eles. Em muitos sistemas, criar uma thread é cem vezes mais rápido do que criar um processo;

Uma terceira razão é também um argumento de desempenho. O uso de threads não resulta em ganho de desempenho quando todos eles são CPU-bound (limitados pela CPU, isto é, muito processamento com pouca E/S). No entanto quando há grande quantidade de computação e E/S, as threads permitem que essas atividades se sobreponham e, desse modo, aceleram a aplicação;

Finalmente, as threads são úteis em sistemas com múltiplas CPUs, para os quais o paralelismo real é possível;

Page 8: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 8

Uso de threads

Exemplos de uso de threads:

– Em um editor de texto, pode existir uma thread que fica interagindo com o usuário, atendendo as solicitações imediatistas do usuário, e pode haver uma segunda thread trabalhando em background que salva o arquivo automaticamente de tempos em tempos;

– Um segundo exemplo seria com um servidor web. A solicitação de site que chega a um servidor web, pode ser delegaga a uma thread, enquanto isso o servidor web fica livre para receber novas solicitações;

Aplicações (servidoras) que trabalham com várias threads e que atendam solicitações de outras aplicações são chamadas multithread;

Aplicações multithreads conseguem paralelismo na execução, mesmo em cenários de chamadas de sistema blocante;

Page 9: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 9

SISTEMAS OPERACIONAIS

O modelo de thread clássico

Page 10: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 10

O modelo de threads clássico O que as threads acrescentam ao modelo de processo é permitir que

múltiplas execuções ocorram no mesmo ambiente do processo, com um grande grau de independência uma da outra;

Ter múltiplas threads executando em paralelo em um processo é análogo a múltiplos processos executando em paralelo em um único computador;

As threads compartilham um mesmo espaço de endereçamento e outros recursos. Os processos compartilham um espaço físico de memória, disco, impressoras e outros recursos;

Como as threads possuem algumas das propriedades dos processo, elas são por vezes chamadas de processos leves;

O termo multithread é também usado para descrever a situação em que se permite a existência de múltiplas threads no mesmo processo;

Algumas CPUs têm suporte de hardware direto para multithread e permitem a ocorrência de chaveamento de threads em uma escala de tempo de nanossegundos;

Page 11: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 11

O modelo de threads clássico

Figura 2 – Processos e Threads

Page 12: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 12

O modelo de threads clássico

Quando um processo com múltiplas threads é executado em um sistema com uma única CPU, as threads esperam a sua vez para executar;

Ao chavear entre vários processos, o sistema induz a ilusão de processos sequenciais distintos executando em paralelo. O multithread funciona do mesmo modo;

Threads distintas em um processo não são independentes como processos distintos. Todas as threads têm exatamente o mesmo espaço de endereçamento, o que significa que elas também compartilham as mesmas variáveis globais;

Como cada thread pode ter acesso a qualquer endereço de memória dentro do espaço de endereçamento do processo, uma thread pode ler, escrever ou até mesmo apagar completamente a pilha de outra thread;

Page 13: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 13

O modelo de threads clássico Não há proteção entre threads porque (1) é impossível e (2) não seria

necessário. Já no caso de processos diversos, que podem ser de usuários diferentes e mutuamente hostis existe a necessidade de proteção;

Assim como em processos tradicionais (isto é processos com apenas uma thread), uma thread pode estar em um dos vários estados: em execução, bloqueado, pronto ou finalizado. As transições entre os estados da thread são as mesmas transições entre os estados dos processos;

É importante perceber que cada thread tem sua própria pilha (a pilha grava o status de execução do processo/thread);

Quando ocorre a execução de múltiplas threads, os processos normalmente iniciam com uma única thread. Essa thread tem a capacidade de criar novas threads;

Algumas vezes as threads são hierarquicas, com um relacionamento pai-filho, mas com frequencia esse relacionamento não existe, uma vez que todos os threads são iguais;

Page 14: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 14

O modelo de threads clássico

Figura 3 – Thread no sistema operacional

Page 15: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 15

O modelo de threads clássico

Quando termina o seu trabalho uma thread chama uma rotina (thread_exit) de finalização. Ela então desaparece e não é mais escalonável;

Uma thread também pode esperar pela saída de uma thread específica, chamando o procedimento thread_join. Essa rotina bloqueia a thread que a executou até que a thread específica tenha terminado;

Outra chamada comum de thread é a thread_yield, que permite que uma thread desista voluntariamente da CPU para deixar outra thread executar. Essa chamada é importante porque não há uma interrupção de relógio para forçar um tempo compartilhado, como existe com processos. Assim é importante que as threads sejam corteses;

Mesmo sendo úteis em muitas situações, as threads também introduzem várias complicações no modelo de programação. Só para começar, considere os efeitos das chamada de sistema fork. Se o processo pai tiver múltiplos threads, o processo filho não deveria tê-los também?

Page 16: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 16

O modelo de threads clássico

Contudo, se o processo filho possuir tantas threads quanto o pai, o que acontece se uma thread do pai estiver bloqueado em uma chamada read do teclado. Agora são dois threads bloqueados esperando entrada pelo teclado, um no pai e outro no filho? Quando uma linha for digitada, ambas as threads conterão uma cópia dela? Somente o pai? Somente o filho? O mesmo problema existe com as conexões de rede em aberto.

Outra classe de problemas está relacionada ao fato das threads compartilharem muitas estruturas de dados. O que acontece se uma thread fechar um arquivo enquanto outra estiver ainda lendo o mesmo arquivo? Suponha que uma thread perceba que exista pouca memória e comece a alocar mais memória. No meio dessa tarefa, ocorre um chaveamento entre threads, e então o novo thread perceba que há pouca memória e comece também a alocar mais memória;

Todos os problemas podem ser resolvidos com certa dificuldade, mas programas multithreads devem ser pensados e projetados com cuidado para que funcionem corretamente;

Page 17: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 17

SISTEMAS OPERACIONAIS

Threads POSIX

Page 18: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 18

Threads POSIX

Para possibilitar criar threads portáteis o IEEE definiu um padrão para threads, baseado na padronização POSIX. Essas threads passam a ser chamadas de pthreads;

Exemplos de chamadas pthreads (existem mais de 60);

Chamada de thread Descrição

pthread-create Cria uma nova thread

pthread_exit Conclui a chamada da thread

pthread_join Espera que uma thread específica seja terminada

pthread_yield Libera a CPU para que outra thread seja executada

pthread_attr_init Cria e inicializa uma estrutura de atributos da thread

pthread_attr_destroy Remove uma estrutura de atributos da thread

Tabela1 – Chamadas de sistemas para threadsl

Page 19: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 19

Threads POSIX

Toda as threads Pthreads têm certas propriedades. Cada uma tem um identificador, um conjunto de registros (inclusive um contador de programa), e um conjunto de atributos, que são armazenados em uma estrtutura

Os atributos da pthread incluem o tamanho da pilha , os parâmetros de escalonamento e outros ítens necessários à utilização da thread;

Quando uma thread terminou o trabalho para o qual foi designado, pode concluir a chamada com pthread_exit. Essa chamada interrompe a thread e libera a sua pilha;

Page 20: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 20

SISTEMAS OPERACIONAIS

Pthread_create

Page 21: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 21

Pthread_create()

Essa primitiva é utilizada para criar threads;

A função pthread_create tem a seguinte sintaxe:

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

*thread → é um ponteiro para uma variável do tipo pthread_t, responsável pela identificação da thread recém criada;

*attr → é um ponteiro para os atributos que são armazenados em uma variável do tipo pthread_att.r_t. Ela permite que o programador defina alguns atributos especiais como política de escalonamento, seu escopo de execução, dentre outros. Para utilizar o padrão do sistema deve ser passado NULL;

start_routine → é o nome da função que será executada pela thread;

Page 22: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 22

Pthread_create()

*arg → é passado como argumento para a rotina (dados para thread recém criada;

A função pthread_create() retorna zero caso tenha sucesso na criação de uma thread ou -1 no caso de erro;

Exercícios exemplos: prog1, prog2, prog3, prog4, prog5 e prog6

Page 23: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 23

SISTEMAS OPERACIONAIS

Pthread_join

Page 24: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 24

Pthread_join()

A primitiva pthread_join() suspende o processamento da thread que a chamou até que a thread identificada na função termine normalmente através da função pthread_exit() ou seja cancelada;

Sintaxe:

#include <pthread.h>

int pthread_join( pthread_t th, void **thread_return);

Essa chamada de sistema recebe como parâmetro a identificação da thread que vai ser esperada e o valor de retorno desta. Se o parâmetro thread_return for NULL, o valor de retorno é descartado;

O valor de retorno dessa função é zero para operação bem sucedida e um valor diferente de zero para o caso de erro;

Exemplo: prog7

Page 25: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 25

SISTEMAS OPERACIONAIS

Pthread_yield

Page 26: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 26

Pthread_yield()

A primitiva pthread_yield() permite que uma thread desista voluntariamente de uma CPU para deixar outra thread executar;

Sintaxe:

#include <pthread.h>

int pthread_yield( void);

O valor de retorno dessa função é zero para operação bem sucedida e um valor diferente de zero para o caso de erro;

Exemplo: prog8

Page 27: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 27

SISTEMAS OPERACIONAIS

Implementação de threads no espaço do usuário

Page 28: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 28

Threads no espaço do usuário

Há dois modos principais de implementar um pacote de threads: no espaço do usuário e no núcleo. Também é possível uma implementação híbrida;

Threads no espaço do usuário, significa que as threads são implementadas e gerenciadas somente no espaço do usuário. O núcleo do sistema operacional fica alheio a presença de threads;

Uma vantagem da implementação de threads no espaço do usuário é que as threads podem ser implementadas em um sistema operacional que não suporte threads. Com essa abordagem as threads são implementadas na forma de bibliotecas;

Quando as threads são gerenciadas no espaço do usuário, cada processo precisa de sua própria tabela de threads para manter o controle das threads naquele processo. Essa tabela é análoga à tabela de processos no núcleo;

Page 29: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 29

Threads no espaço do usuário A tabela de threads é gerenciada pelo sistema de tempo de execução.

Quando uma thread vai para o estado pronto ou bloqueado, a informação necessária para reiniciá-la é armazenada na tabela de threads, exatamente do mesmo modo como o núcleo armazena as informações sobre os processos na tabela de processos;

Quando uma thread faz algo que possa bloqueá-la localmente – por exemplo, espera que uma outra thread em seu processo termine o seu trabalho - , ela chama uma rotina do sistema de tempo de execução. Essa rotina verifica se a thead deve entrar no estado bloqueado. Em caso afirmativo, ele armazena os registradores da thread na tabela de threads, busca na tabela por uma thread pronto para executar e recarrega os registradores da máquina com novos valores salvos da threads. Logo que o ponteiro de pilha e o contador de programa forem alterados, a nova thread reviverá automaticamente;

Se a máquina tiver uma instrução que salve todos os registradores e outra que carregue todos eles, o chaveamento da thread poderá ser feito com poucas instruções;

Page 30: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 30

Threads no espaço do usuário

Fazer o chaveamento de threads é, pelo menos, de uma ordem de magnitude mais rápida que desviar o controle para o núcleo – esse é um forte argumento em favor dos pacotes de threads de usuário;

Outra diferença fundamental é que quando uma thread decide parar de executar – por exemplo, quando executa a chamada thread_yield -, o código desta pode salvar a informação da thread na própria tabela de threads. Mais ainda: o escalonador de thread pode ser chamado pelo código thread_yield para selecionar uma outra thread para executar. A rotina que salva o estado da thread e o escalonador são apenas rotinas locais, de modo que é muito mais eficiente involcá-las do que fazer uma chamada do núcleo. Entre outras coisas não é necessário passar do modo usuário para o modo núcleo, não se precisa de nenhum chaveamento de contexto, a cache da memória não tem que ser esvaziada e assim por diante. Isso tudo agiliza o escalonamento de threads;

Page 31: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 31

Threads no espaço do usuário

Apesar dessas vantagens as threads implementadas no espaço do usuário também tem seus problemas. O primeiro deles é como implementar as chamadas de sistemas com bloqueio;

Outro problema se refere a falta de página (page fault), caso onde o processo solicita acesso a uma página sua que não está na RAM. Quando isso acontece o sistema operacional bloqueia o processo e por tabela todas a threads presentes nesse processo;

Outro problema com pacotes de threads de usuário é que, se uma thread começa a executar, nenhuma outra thread naquele processo executará sequer uma vez, a menos que a primeira thread, voluntariamente, abra mão da CPU. Em um processo único não há interrupções de relógio, o que torna impossível escalonar threads pelo escalonamento circular (round-robin). A mesmo que uma thread ceda voluntariamente a vez para outra, o escalonador nunca terá oportunidade de fazê-lo;

Page 32: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 32

SISTEMAS OPERACIONAIS

Implementação de threads no núcleo

Page 33: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 33

Threads no núcleo Nesse modo o núcleo sabe sobre as threads e os gerencia;

Nesse cenário não há mais a necessidade de uma tabela de threads para cada processo. Em vez disso, o núcleo tem uma tabela de threads que acompanha todas as threads do sistema. Quando uma thread quer criar uma nova thread ou destruir uma já existente, ela faz uma chamada ao núcleo, que realiza então a criação, ou a destruição atualizando a tabela de threads do núcleo;

A tabela de threads do núcleo contém os registradores, o estado e outras informações de cada thread. Essas informações constituem um subconjunto das informações que núcleos tradicionais mantêm sobre cada um dos seus processos. O núcleo também mantém a tradicional tabela de processos;

Nesse cenário tadas as chamadas que possam bloquear uma thread são implementadas como chamadas de sistemas. Quando uma thread é bloqueada outra thread do mesmo processo (se algum estiver pronto) passa a tomar posse do processador;

Page 34: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 34

Threads no núcleo

Há um custo maior que no espaço do usuário em se criar e destruir threads gerenciadas via núcleo, por isso alguns sistemas operacionais adotam uma abordagem ambientalmente correta, reciclam as threads;

Embora as threads de núcleo resolvam alguns problemas, eles não resolvem todos. Por exemplo, o que acontece quando um processo multithread é bifurcado? O novo processo tem tantas threads como o anterior ou tem apenas um?

Outra questão são os sinais. Lembramos que os sinais são enviados para processos, não para threads, pelo menos no modelo clássico. Quando um sinal chega, qual thread deveria controlá-lo?

Embora threads de núcleo sejam melhores que threads de usuário em aspectos importantes, também são indiscutivelmente mais lentos.

Para tentar combinar as vantagens de threads de usuário com as de núcleo, tem se falado em soluções híbridas.

Page 35: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 35

SISTEMAS OPERACIONAIS

Threads pop-up

Page 36: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 36

Threads pop-up

Threads são bastante úteis em sistemas distribuídos. Um exemplo importante é como as mensagens que chegam são tratadas. A abordagem tradicional é bloquear um processo ou uma thread em uma chamada de sistema receive e aguardar que uma mensagem chegue;

Contudo, um caminho completamente diferente também é possível, na qual a chegada de uma mensagem faz com que o sistema crie uma nova thread para lidar com a mensagem. Essa thread é chamada tread pop-up;

Um ponto fundamental das threas pop-up é que como são novas, não tem qualquer história – registradores, pilha etc. - que deva ser restaurada. Cada thread recém-criada é idêntica a anterior. Isso possibilita que sejam criadas rapidamente;

A vantagem do uso de threads pop-up é que a latência entre a chegada da mensagem e o início do processamento pode ser muito pequena;

Exemplo de programa: exec9

Page 37: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 37

Referência Bibliográfica

Sistemas Operacionais Modernos - Andrew S. Tanenbaum. 3ª edição, 2009;

www.google.com.br.

Page 38: Aula04 Processos Thread

IFTO-Palmas Prof. Helder 38

Programa exemplo

Um exemplo de programa que pode ser feito em sala:

Faça um programa que seja executado de forma sequencia: pede usuário e senha (6 caracteres cada) e depois conte de 1 até 100.0000

Agora refaça o mesmo programa com threads. A thread criada irá executar a parte que pede o usuário e a senha e a thread progenitora vai contar até 100.000. Quando você terminar de digitar a senha é capaz que a contagem já tenha sido termina.

Isso demonstra a vantagem de uso de threads ou forks mesmo em uma máquina que tenha apenas um processador com um núcleo;