Sistemas Distribuídos

Documentos relacionados
SISTEMAS OPERACIONAIS

Processos e Threads (partes I e II)

Revisão Ultima aula [1/2]

Udesc/Ceplan Bacharelado em Sistemas de Informação Sistemas Operacionais. Prof. Alexandre Veloso

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

Sistemas Operacionais Aula 08: Sincronização de Processos. Ezequiel R. Zorzal

Sincronização e Comunicação entre Processos. Adão de Melo Neto

Sistemas Operacionais

Sistemas Operacionais Sincronização e Comunicação entre Processos

Arquitetura de Computadores. Tipos de Instruções

Notas da Aula 4 - Fundamentos de Sistemas Operacionais

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

Disciplina: Sistemas Operacionais - CAFW-UFSM Professor: Roberto Franciscatto

Sistemas Operacionais. Técnicas de Implementação de Exclusão Mútua. Aula VI Prof. Rosemary Silveira

Métodos de Sincronização do Kernel

Programação Concorrente

Sistemas Operacionais

Programação Concorrente em java - Exercícios Práticos Abril 2004

Sistemas Operacionais Processos e Threads

Threads em Java. Sistemas Operacionais - Laboratório Professor Machado

THREADS EM JAVA. George Gomes Cabral

Capítulo 2 Processos e Threads Prof. Fernando Freitas

Sistemas Operacionais. Prof. André Y. Kusumoto

EXEMPLO: Processo para atualização da hora Processo para monitoramento da necessidade de proteção de tela. Figura Exemplo

Como foi exposto anteriormente, os processos podem ter mais de um fluxo de execução. Cada fluxo de execução é chamado de thread.

Threads e Concorrência em Java (Material de Apoio)

SISTEMAS OPERACIONAIS ABERTOS Prof. Ricardo Rodrigues Barcelar

SISTEMAS OPERACIONAIS CAPÍTULO 3 CONCORRÊNCIA

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064

Programação Concorrente Processos e Threads

Sistema Operacional. Processo e Threads. Prof. Dr. Márcio Andrey Teixeira Sistemas Operacionais

BARRAMENTO DO SISTEMA

Sistemas Operacionais

Recursos. Um recurso é ou um dispositivo físico (dedicado) do hardware, ou Solicitar o recurso: esperar pelo recurso, até obtê-lo.

O mecanismo de alocação da CPU para execução de processos constitui a base dos sistemas operacionais multiprogramados.

Carlos Eduardo Batista Centro de Informática - UFPB bidu@ci.ufpb.br

Disciplina de Sistemas Distribuídos. Sincronização em SD. Prof. M.Sc. Alessandro Kraemer Kraemer

Deadlocks. Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

Sistemas Operacionais

Java : Comunicação Cliente-Servidor.

Conceito de processo como uma unidade de trabalho em um sistema moderno de tempo compartilhado. Estados de um processo.

ArpPrintServer. Sistema de Gerenciamento de Impressão By Netsource Rev: 02

Processos. Adão de Melo Neto

Sistemas Operativos. Threads. 3º ano - ESI e IGE (2011/2012) Engenheiro Anilton Silva Fernandes (afernandes@unipiaget.cv)

Sistemas Operacionais. Prof. M.Sc. Sérgio Teixeira. Aula 04 - Concorrência. Cursos de Computação

IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira

A memória é um recurso fundamental e de extrema importância para a operação de qualquer Sistema Computacional; A memória trata-se de uma grande

Sistemas Operacionais

Ministério da Educação Secretaria de Educação Profissional e Tecnológica Instituto Federal de Educação, Ciência e Tecnologia do Rio Grande do Sul

MC714 - Sistemas Distribuídos. Leandro Villas

Sistemas Operacionais

Notas da Aula 6 - Fundamentos de Sistemas Operacionais

Tabela de Símbolos. Análise Semântica A Tabela de Símbolos. Principais Operações. Estrutura da Tabela de Símbolos. Declarações 11/6/2008

Comm5 Tecnologia Protocolo MI. Protocolo. Família MI

Sistema Operacional. Prof. Leonardo Barreto Campos 1

Sistemas Operacionais

O hardware é a parte física do computador, como o processador, memória, placamãe, entre outras. Figura 2.1 Sistema Computacional Hardware

O que veremos nesta aula? Principais Aspectos de Sistemas Operacionais. Visão geral de um sistema computacional

Sistemas Operacionais. Prof. André Y. Kusumoto

28/9/2010. Paralelismo no nível de instruções Processadores superescalares

OCOMON PRIMEIROS PASSOS

Organização e Arquitetura de Computadores

Sincronização. Cooperação entre Processos

CAPÍTULO 2 CARACTERÍSTICAS DE E/S E PORTA PARALELA

Prof.: Roberto Franciscatto. Capítulo 1.2 Aspectos Gerais

Prof.: Roberto Franciscatto. Capítulo 1.1 Introdução

Disciplina: Sistemas Operacionais - CAFW-UFSM Professor: Roberto Franciscatto

Manual Sistema de Autorização Online GW

9 - Sincronização e Comunicação entre Processos

Sistemas Distribuídos

INDICE 1. INTRODUÇÃO CONFIGURAÇÃO MÍNIMA INSTALAÇÃO INTERLIGAÇÃO DO SISTEMA ALGUNS RECURSOS SERVIDOR BAM...

Sincronização de Processos (5) Troca de Mensagens

BACHARELADO EM SISTEMAS DE INFORMAÇÃO EaD UAB/UFSCar Sistemas de Informação - prof. Dr. Hélio Crestana Guardia

Ao ligar o equipamento, você verá a mensagem abaixo, o objetivo dela é fazer a configuração mínima para LOGAR ao servidor da Internet.

Organização de Computadores 1

Sincronização de Processos (1) Mecanismos de busy wait

Aula 3. Sistemas Operacionais. Prof: Carlos Eduardo de Carvalho Dantas

SIMULADOR DE ROTEAMENTO DE PACOTES (V. 3 20/05/2010)

Introdução aos Sistemas

Sistemas Distribuídos. Aleardo Manacero Jr.

Universidade da Beira Interior. Sistemas Distribuídos

Manual do usuário. Softcall Java. versão 1.0.5

MODELO CLIENTE SERVIDOR

ARQUITETURA DE COMPUTADORES

28/9/2010. Unidade de Controle Funcionamento e Implementação

Prof. Antonio Fundamentos de Sistemas Operacionais UNIP/2015

Programação Concorrente Introdução

Processamento de Dados

Manual de Administração DPS Printer 2.1 NDDigital S/A - Software

Computação Concorrente (MAB-117) Monitores

SISTEMAS DISTRIBUÍDOS

Transcrição:

Sistemas Distribuídos Processos e Threads Gustavo Reis gustavo.reis@ifsudestemg.edu.br

- 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.

- 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)

- 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.

- Estados de Processo 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. Bloqueado Em execução 1 2 3 4 Pronto 1. O processo bloqueia aguardando uma entrada 2. O escalonador seleciona outro processo 3. O escalonador esse processo 4. A entrada torna-se disponível

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).

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 Dois processos querem acessar a memória compartilhada ao mesmo tempo Processo A Processo B 4 5 6 7 Diretório de spool... abc prog.c prog.h... out = 4 in = 7

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.

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.

Regiões Críticas A entra na região crítica A deixa a região crítica Processo A B tenta entrar na região crítica B entra na região crítica B deixa a região crítica Processo B Exclusão mútua usando regiões críticas B bloqueado T1 T2 T3 T4 Tempo

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.

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.

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

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.

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*/ }

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.

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.

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.

Dormir e Acordar Problema do produtor-consumidor: #define N 100 //número de lugares no buffer int count = 0; //número de itens no buffer void 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 } }

Dormir e Acordar Problema do produtor-consumidor: Qual o problema que pode acontecer?

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.

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.

Semáforos P(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

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).

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);

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.

- 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.

- 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.

- 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.

- 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 ); } }

- 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 ); } }

- 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();

- 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 (...)