Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos...

33
Sistemas Distribuídos Gustavo Reis [email protected] Processos e Threads

Transcript of Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos...

Page 1: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

Sistemas Distribuídos

Gustavo Reis

[email protected]

Processos e Threads

Page 2: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- O que são Processos?

Uma abstração de um programa em execução.

Mantêm a capacidade de operações (pseudo)concorrentes, mesmo quando há apenas uma CPU disponível.

Transformam uma única CPU em várias CPUs virtuais.

Possuem programa, entrada, saída e um estado.

Um único processador pode ser compartilhado entre os vários processos, com algum algoritmo de escalonamento usado para determinar quando parar o trabalho sobre um processo e servir outro.

Page 3: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Criação de Processos

Em sistemas muito simples, ou em sistemas projetados para executar apenas uma única aplicação, pode ser possível que todos os processos que serão necessários seja criados quando o sistema é ligado.

Em sistemas de propósito geral, é necessário algum mecanismo para criar e terminar processos durante a operação, quando for preciso.

Há quatro eventos principais que fazem com que processos sejam criados: Iníco do sistema

Execução de uma chamada de sistema de criação de processo por um processo em execução

Uma requisição do usuário para criar um novo processo

Início de uma tarefa em lote (batch lote)

Page 4: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Estados de Processo

Embora cada processo seja uma entidade independente, com seu próprio contador de programa e estado interno, muitas vezes os processos precisam interagir com outros.

Um processo pode gerar uma saída que outro processo usa como entrada.

Ex.:

cat chapter1 chapter2 chapter3 | grep tree

O primeiro processo, que executa cat, gera como saída a concatenação dos três arquivos.

O segundo processo, que executa grep, seleciona todas as linhas contendo a palavra “tree”.

Page 5: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Estados de Processo

Em execução

ProntoBloqueado

1 23

41. O processo bloqueia aguardando uma entrada2. O escalonador seleciona outro processo3. O escalonador esse processo4. A entrada torna-se disponível

Estados:

Em execução → realmente usando a CPU naquele momento.

Pronto → executável; temporariamente parado para dar lugar a outro processo.

Bloqueado → incapaz de executar enquanto não ocorrer um evento externo.

Page 6: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Frequentemente processos precisam se comunicar com outros (IPC – interprocess communication).

Há três tópicos em relação a comunicação de processos:

Como um processo passa informação para outro;

Como garantir que dois ou mais processos não entrem em conflito (concorrência pelo mesmo recurso);

Sequência adequada quando existirem dependências (produtor/consumidor).

Page 7: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Condições de Corrida

Dois ou mais processos estão lendo ou escrevendo algum dado compartilhado e cujo resultado depende de quem executa precisamente e quando a executa.

Ex.: spool de impressão

abc

prog.c

prog.h

Diretório de spool...

.

.

.

out = 4

in = 7

4567

Processo A

Processo B

Dois processos querem acessar a memória compartilhada ao mesmo tempo

Page 8: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Regiões Críticas

O que fazer para evitar condições de disputa?

Exclusão Mútua → modo de assegurar que outros processos sejam impedidos de usar uma variável ou um arquivo compartilhado que já estiver em uso por um processo.

Parte do programa que acessa um recurso compartilhado é chamada de região crítica.

Page 9: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Regiões Críticas

É preciso satisfazer quatro condições para chegar a uma boa solução que impeça condições de disputa:

Dois processos nunca podem estar simultaneamente em suas regiões críticas;

Nada pode ser afirmado sobre a velocidade ou sobre o número de CPUs;

Nenhum processo executando fora de sua região crítica pode bloquear outros processos;

Nenhum processo deve esperar eternamente para entrar em sua região crítica.

Page 10: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Regiões Críticas

Processo A

Processo B

T1 T2 T3 T4

A entra na região crítica A deixa a região crítica

B tenta entrar na

região crítica

B entra na região crítica

B deixa a região crítica

B bloqueado

TempoExclusão mútua usando regiões críticas

Page 11: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Exclusão Mútua Desabilitando interrupções

Em sistemas de processador único, a solução mais simples é aquela em que cada processo desabilita todas as interrupções logo depois de entrar em sua região crítica e as reabilita imediatamente antes de sair dela.

Com as interrupções desligadas, a CPU não será mais chaveada para outro processo. Desta forma um processo pode verificar e atualizar a memória compartilhada sem temer a intervenção de um outro processo.

De modo geral, esta abordagem não é interessante, porque não é prudente dar aos processos dos usuários o poder de desligar interrupções. Pois o usuário pode desabilitar as interrupções e não mais habilitar. Além disso, se o sistema for multicore, desabilitar as interrupções afetará somente a CPU que executou a instrução disable. As outras continuarão executando e tendo acesso à memória compartilhada.

Page 12: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Exclusão Mútua Variáveis do tipo trava (lock)

Outra alternativa com solução através de software.

Existência de uma única variável compartilhada para controle da região crítica. Inicialmente o valor da variável é zero.

Para entrar em sua região crítica, o processo testa antes se o valor da variável é zero. Em caso verdadeiro, o processo altera essa variável para um e entra na região crítica. Se a variável já estiver com o valor um, o processo simplesmente aguardará até que ela se torne zero.

Desvantagem: quando um processo lê o conteúdo da variável com valor zero e antes que ele modifique para um, outro processo é escalonado e altera o valor para um. Ao voltar a executar, o primeiro processo também coloca o valor um na variável e, assim, os dois processos estarão em suas regiões críticas ao mesmo tempo.

Page 13: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Exclusão Mútua Chaveamento obrigatório

while (TRUE) {

while (turn != 0);

turn = 1;

critical_region();

turn = 0;

noncritical_region();

}

(a)

while (TRUE) {

while (turn != 0);

turn = 1;

critical_region();

turn = 0;

noncritical_region();

}

(b)

Solução proposta para o problema da região crítica. (a) Processo 0. (b) Processo 1

Page 14: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Exclusão Mútua Solução de Peterson

Consiste em duas rotinas (enter_region e leave_region).

Antes de usar as variáveis compartilhadas (ou seja, antes de entrar em sua região crítica), cada processo chama enter_region com seu próprio número de processo, 0 ou 1, como parâmetro.

Essa chamada fará com que ele fique esperando, se necessário, até que seja seguro entrar.

Depois que terminou de usar as variáveis compartilhadas, o processo chama leave_region para indicar seu término e permitir que outro processo entre, se assim desejar.

Page 15: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Exclusão Mútua Solução de Peterson

#define FALSE 0

#define TRUE 1

#define N 2 /*número de processos*/

int turn; /*de quem é a vez?*/

int interested[N]; /*todos os valores 0 ou 1*/

void enter_region(int process); { /*processo é 0 ou 1*/

int other; /*número do outro processo*/

other = 1 – process; /*o oposto do processo*/

interested[process] = TRUE; /*configura qual processo está interessado*/

turn = process; /*altera o valor de turn*/

while (turn == process && interested[other] == TRUE) /*comando nulo*/;

}

void leave_region(int process) { /*processo: quem está saindo*/

interested[process] = FALSE; /*indica a saída da região crítica*/

}

Page 16: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Exclusão Mútua Instrução TSL

Requer um pequeno auxílio do hardware.

Muitos computadores – especialmente aqueles projetados com múltiplos processadores – têm uma instrução TSL RX, LOCK (test and set lock – teste e atualize a variável de trava).

As operações de leitura e armazenamento da palavra são seguramente indivisíveis – nenhum outro processador pode ter acesso à palavra na memória enquanto a instrução não terminar.

A CPU que está executando a instrução TSL impede o acesso ao barramento de memória para proibir que outras CPUs tenham acesso à memória enquanto ela não terminar.

Page 17: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Dormir e Acordar A solução de Peterson e a solução com base em TSL são corretas,

mas ambas apresentam o defeito de precisar da espera ociosa.

Em essência, o que essas soluções fazem é: quando quer entrar em uma região crítica, um processo verifica se sua entrada é permitida. Se não for, ele ficará em um laço esperando até que seja permitida a entrada.

Problema da inversão de prioridade: Dois processos → H, com alta prioridade, e L, com baixa prioridade.

As regras de escalonamento são tais que H é executado sempre que estiver no estado de pronto.

Em certo momento, com L em sua região crítica, H torna-se pronto pra executar.

Agora H inicia uma espera ocupada, mas, como L nunca é escalonado enquanto H está executando, L nunca tem a oportunidade de deixar sua região crítica e, assim, H fica em um laço infinito.

Page 18: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Dormir e Acordar Problema do produtor-consumidor:

Dois processos compartilham um buffer comum e de tamanho fixo.

Um deles, o produtor, coloca informação dentro do buffer e o outro, o consumidor, a retira.

O problema se origina quando o produtor quer colocar um novo item no buffer, mas ele está cheio. A solução é colocar o produtor para dormir e só despertá-lo quando o consumidor remover um ou mais itens.

Da mesma maneira, se o consumidor quiser remover um item do buffer e perceber que está vazio, ele dormirá até que o produtor coloque algo no buffer e o desperte.

O código do consumidor é similar.

Page 19: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Dormir e Acordar Problema do produtor-consumidor:

#define N 100 //número de lugares no bufferint count = 0; //número de itens no buffervoid producer(void) { int item; while(TRUE) { //repita para sempre item = produce_item(); //gera o próximo item if (count==N) sleep(); //se o buffer estiver cheio, vá dormir inset_item(item); //ponha um item no buffer count++; //incremente o contador de itens no buffer if (count==1) wakeup(consumer); //o buffer está vazio? }} void consumer(void) {

int item; while(TRUE) { //repita para sempre if (count==0) sleep(); //se o buffer estiver vazio, vá dormir item = remove_item(); //retire o item do buffer count--; //decresça de um o contador de itens no buffer if (count==N-1) wakeup(producer); //o buffer estava cheio? consume_item(item); //imprima o item }}

Page 20: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Dormir e Acordar Problema do produtor-consumidor:

Qual o problema que pode acontecer?

Page 21: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Dormir e Acordar Problema do produtor-consumidor:

Caso aconteça condição de disputa seria possível acontecer a seguinte situação: o buffer está vazio e o consumidor acabou de ler a variável count para verificar se seu valor é 0. Nesse instante, o escalonador decide parar de executar o consumidor temporariamente e começa a executar o produtor. O produtor insere um item no buffer, incrementa a variável count e percebe que seu valor agora é 1. Inferindo que o valor de count era 0 e que o consumidor deveria ir dormir, o produtor chama wakeup para acordar o consumidor.

Infelizmente, o consumidor ainda não está logicamente adormecido; então, o sinal de acordar é perdido. Na próxima vez em que o consumidor executar, testará o valor de count anteriormente lido por ele, verificará que o valor é 0 e dormirá. Mais cedo ou mais tarde o produtor preencherá todo o buffer e também dormirá. Ambos dormirão para sempre.

Page 22: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Semáforos Criado pelo matemático holandês E. W. Dijkstra em1965

É um tipo abstrato de dado composto por um valor inteiro e uma fila de processos.

Permite somente duas operações: P (down) e V (up).

Quando um processo executa a operação P sobre um semáforo, o seu valor é decrementado. Caso o novo valor seja negativo, o processo é bloqueado e inserido no fim da fila desse semáforo.

Quando um processo executa a operação V sobre um semáforo, o seu valor é incrementado. Caso exista processo bloqueado na fila desse semáforo, o primeiro processo da fila é liberado.

Page 23: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

SemáforosP(S):

S.valor = S.valor – 1;

se S.valor < 0

Então bloqueia o processo, insere em S.fila;

V(S):

S.valor = S.valor + 1;

se S.valor <= 0

Então retira processo P de S.fila, acorda P

Page 24: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Semáforos Para que semáforos funcionem corretamente, é essencial que as

operações P e V seja atômicas.

Semáforos tornam a proteção da seção crítica muito simples.

Para cada estrutura de dados compartilhada, deve ser criado um semáforo S inicializado com valor 1.

Todo processo, antes de acessar a estrutura, deve executar um P(S), ou seja, a operação P sobre o semáforo S associado com a estrutura de dados em questão.

Ao sair da seção crítica, o processo executa V(S).

Page 25: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Troca de Mensagens Processos executando em diferentes máquinas não possuem variáveis

compartilhadas.

Eles trocam informações através de mensagens via uma rede de comunicação.

Tipicamente, o mecanismo que permite a troca de mensagens entre processos é implementado pelo sistema operacional.

Ele é acessado através de duas chamadas de sistema básica: Send e Receive.

send(destino,&mensagem);

receive(origem,&mensagem);

Page 26: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Comunicação entre Processos

Troca de Mensagens Produtor-consumidor com troca de mensagem (caixa postal)

Local para armazenar temporariamente um certo número de mensagens.

Quando as caixas postais são usadas, os parâmetros de endereço nas chamadas send e receive são as caixas postais, não os processos.

Ao tentar enviar para uma caixa postal que esteja cheia, um processo é suspenso até que uma mensagem seja removida daquela caixa postal e dê lugar a uma nova.

Page 27: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- O que são Threads?

Também chamados de processos leves, permitem múltiplas atividades dentro de um único processo;

Fluxo de controle sequencial isolado dentro de um programa;

Como um programa sequencial qualquer, uma thread tem um começo, uma sequencia de comandos e um fim;

Threads permitem que um programa simples possa executar várias tarefas diferentes ao mesmo tempo, independentemente umas das outras.

Page 28: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Criando Threads em Java

Em Java, as threads se constituem de instâncias da classe Thread que fornecem suporte a comunicação concorrente;

A classe Thread provê métodos necessários para criar e controlar threads (independentemente da plataforma usada) e executá-los concorrentemente;

O corpo de uma thread é o seu método run(), e é nele que são executadas as tarefas às quais thread se destina.

Page 29: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Duas formas de criar Threads

Criando uma subclasse da classe Thread e definindo o seu método run() de maneira adequada à realização da tarefa do thread;

Criando uma instância de Thread que recebe como parâmetro um objeto que implemente a interface Runnable - esse objeto providenciará o método run() para a thread.

Page 30: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Usando Herança

Usando herança, a classe deve sobrescrever o método public void run():

class Tarefa1 extends Thread {

public void run() {

for(int i=0; i<1000; i++)

System.out.println(“Usando herança”);

}

}

Page 31: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Usando a interface Runnable

A interface Runnable obriga a implementar o método public void run():

class Tarefa2 implements Runnable {

public void run() {

for(int i=0; i<1000; i++)

System.out.println(“Usando Runnable”);

}

}

Page 32: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Exemplo de uso

Para usar as classes Tarefa1 e Tarefa2 devemos fazer:

Thread threadComHeranca = new Tarefa1();

Thread threadComRunnable = new Thread(new Tarefa2());

threadComHeranca.start();

threadComRunnable.start();

Page 33: Processos e Threads - sistemas.riopomba.ifsudestemg.edu.br · - Comunicação entre Processos Exclusão Mútua Desabilitando interrupções Em sistemas de processador único, a solução

- Saída do exemplo

A saída do exemplo seria mais ou menos essa:

Usando Runnable

Usando Herança

Usando Herança

Usando Runnable

Usando Herança

Usando Runnable

(...)