cap. 5 – objetos distribuídos e invocação remota · • precisam invocar operações em...

32
1 SD Cap. 5-6 1 SD Cap. 5-6 Cap. 5 – Objetos Distribuídos e Invocação Remota Aplicação distribuída: conjunto de processos que cooperam entre si; Precisam invocar operações em processos remotos para realizar serviços. Modelos de programação usados: Chamada de procedimentos: extendida no RPC para permitir a chamada de procedimentos remotos; Invocação de métodos: extendida no RMI para permitir a invocação de métodos em objetos remotos; Programação orientada a eventos: permite a objetos receber notificações de eventos em objetos onde registraram interesse. Extendida para permitir notificação sobre eventos distribuídos. Middleware Aplicações RMI, RPC e eventos Protocolo request – reply Representação externa de dados Sistema operacional Aspectos importantes: Transparência de localização: no RPC, quem chama uma função não sabe se ela é local ou não, se roda no mesmo processo ou num diferente. Se for remota, não se sabe onde está o processo que vai ser executado. Recebendo um evento distribuído, o processo não sabe onde está o processo que o gerou. Protocolos: são independentes do sistema de comunicação básico. Diferenças de hardware: são encobertas por operações de marshalling com EDR. Sistema operacional: a aplicação que usa o middleware não depende do SO local. Linguagens diferentes: alguns middlewares permitem independência de linguagem. Um objeto escrito numa linguagem pode invocar métodos em objetos escritos em outra. 5.1.1 Interfaces Na programação por módulos, o relacionamento entre módulos é feito via uma interface. Nela, relaciona-se quais métodos estão disponíveis para acessar determinado módulo. Enquanto a interface permanecer igual, o acesso ao módulo não é alterado, mesmo que a implementação mude. Interfaces em SDs Num programa distribuído, um módulo não pode acessar variáveis de outro. A interface de um módulo não pode especificar acesso a variáveis. O IDL do CORBA permite especificar atributos, mas o acesso não é direto. A plataforma insere funções de consulta e atualização de variáveis automaticamente. Middleware

Upload: vuonghanh

Post on 09-Nov-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

1 SD Cap. 5-6 1 SD Cap. 5-6

Cap. 5 – Objetos Distribuídos e Invocação Remota Aplicação distribuída: conjunto de processos que cooperam entre si; • Precisam invocar operações em processos remotos para realizar

serviços. Modelos de programação usados: • Chamada de procedimentos: extendida no RPC para permitir a

chamada de procedimentos remotos; • Invocação de métodos: extendida no RMI para permitir a

invocação de métodos em objetos remotos; • Programação orientada a eventos: permite a objetos receber

notificações de eventos em objetos onde registraram interesse. Extendida para permitir notificação sobre eventos distribuídos.

Middleware

Aplicações RMI, RPC e eventos

Protocolo request – reply Representação externa de dados

Sistema operacional Aspectos importantes: • Transparência de localização: no RPC, quem chama uma

função não sabe se ela é local ou não, se roda no mesmo processo ou num diferente. Se for remota, não se sabe onde está o processo que vai ser executado. Recebendo um evento

distribuído, o processo não sabe onde está o processo que o gerou.

• Protocolos: são independentes do sistema de comunicação básico.

• Diferenças de hardware: são encobertas por operações de marshalling com EDR.

• Sistema operacional: a aplicação que usa o middleware não depende do SO local.

• Linguagens diferentes: alguns middlewares permitem independência de linguagem. Um objeto escrito numa linguagem pode invocar métodos em objetos escritos em outra.

5.1.1 Interfaces Na programação por módulos, o relacionamento entre módulos é feito via uma interface. Nela, relaciona-se quais métodos estão disponíveis para acessar determinado módulo. Enquanto a interface permanecer igual, o acesso ao módulo não é alterado, mesmo que a implementação mude. Interfaces em SDs Num programa distribuído, um módulo não pode acessar variáveis de outro. A interface de um módulo não pode especificar acesso a variáveis. O IDL do CORBA permite especificar atributos, mas o acesso não é direto. A plataforma insere funções de consulta e atualização de variáveis automaticamente.

Middleware

2 SD Cap. 5-6 2 SD Cap. 5-6

Os mecanismos de passagem de parâmetros das chamadas locais não se aplicam em programas distribuídos (passagem por valor ou por referência). Na interface, a especificação de parâmetros indica apenas input e/ou output:

• Input: parâmetros passados para a função invocada que fornecem valores para o seu algoritmo;

• Output: parâmetros que recebem resultados da função invocada.

Ponteiros não podem ser usados em invocações de funções. Diferença entre RPC e RMI: • Interface de serviço: conjunto de funções disponíveis para

acessar os serviços de um servidor no modelo cliente-servidor; • Interface remota: métodos de um objeto disponíveis para

invocação por outros objetos; o Define parâmetros e forma de acesso; o Aceita passagem de objetos como argumentos; o Permite passagem de referências para objetos.

5.2 Comunicação entre objetos distribuídos

5.2.1 Modelo de Objetos Exceções

Tipos de erros que um processo pode encontrar durante sua execução: • Erros controláveis: valores inconsistentes de argumentos, falha

em encontrar um dado num BD, etc. • Erros externos: falha em acessar arquivos ou sockets, etc. • Erros internos: divisão por zero, endereços de memória

inválidos, etc. • Erros de dependência: ocorrem em processos hierarquicamente

superiores. O modelo de objetos permite colocar tratamento de erros através de comandos throw. Isso evita que o programador insira todos os testes no meio do código de um serviço. O tratamento é colocado em blocos separados e a execução desvia para esses blocos quando um evento é catched pelo programa. Garbage collection Objetos ocupam espaço e devem ser liberados quando não são mais necessários. Algumas linguagens (ex. Java) possuem mecanismos para liberar objetos quando não são mais referenciados. Outras não possuem e obrigam o programador a fazer esse controle (ex. C++). Operação sujeita a erros.

5.2.2 Objetos distribuídos Objetos distribuídos podem se organizar de várias formas. A invocação de seus métodos segue modelos previamente estudados.

3 SD Cap. 5-6 3 SD Cap. 5-6

Um dos pontos importantes é verificar se um determinado objeto (ou método) pode ser invocado concorrentemente (+ de uma invocação no mesmo intervalo – uma invocação feita antes da anterior ser executada). O fato de que os dados de um objeto são acessados apenas pelos seus métodos permite aplicar técnicas de controle: • Ex.: Java - métodos sinchronized; • Objetos podem ser copiados para caches locais, sendo acessados

diretamente; • Invocação via RMI permite acesso ao mesmo objeto por

plataformas diferentes – possíveis conversões são feitas por EDR.

5.2.3 O modelo de objetos distribuídos Tipos de invocação: • Local: feitas dentro do mesmo processo; • Remota: feita entre processos diferentes – podem residir ou não

em máquinas diferentes. Para ser acessado remotamente, um objeto deve ter uma referência remota. Cada objeto remoto deve ter uma interface remota, que especifica quais dos seus métodos podem ser acessados remotamente. Referência a objeto remoto Identificador que permite acessar um objeto remotamente.

É único no sistema inteiro e permite identificar um objeto determinado, independente de sua localização. Seu formato é diferente de uma referência local. Referências remotas podem ser passadas como argumentos. Interfaces remotas A classe de um objeto remoto implementa os métodos de sua interface remota. Outros objetos só podem invocar métodos de um objeto que pertencem a sua interface remota.

5.2.4 Quetões de projeto para RMI Diferenças entre chamadas locais e remotas: • Chamadas locais são executadas exatamente 1 vez; sobre

chamadas remotas já não é sempre assim; • O nível de transparência do RMI precisa ser definido. Semânticas de invocação RMI Escolhas sobre protocolos request-reply: • Mensagens retry: até quando retransmitir uma requisição, antes

de receber a resposta ou assumir que o servidor falhou; • Filtro de duplicados: com a possibilidade de retransmissões, se

o servidor deve usar um filtro; • Retransmissão de resultados: se um histórico deve ser mantido

em vez de re-executar sempre cada comando;

4 SD Cap. 5-6 4 SD Cap. 5-6

Medidas de tolerância a falhas Retransmitir requisições

Filtro de duplicados

Re-executar ou retransmitir

reply

Semânticas de

invocação

Não Não aplicável Não aplicável Maybe Sim Não Re-executar At-least-once Sim Sim Retransmite At-most-once

Obs.: para invocação de métodos locais, a semântica é exactly-once! Transparência No RPC, certas atividades (marshalling, envio de mensagens, retransmissão da requisição após um timeout) são escondidas do programador e realizadas de forma transparente. Com objetos distribuídos, isso é extendido para localizar e contactar objetos remotos. Invocações remotas são diferentes das locais porque envolvem redes. Pode haver falhas de rede ou máquina sem que se possa distinguir uma da outra. A grande questão é se a máquina destino recebeu a msg e se conseguiu executá-la. Isso obriga os objetos remotos a tratamentos para recuperação de cada caso. O atraso de uma invocação remota é enorme comparado a uma operação local. Então, é interessante minimisar esse custo.

Apesar de se procurar por transparência, é interessante que a diferença entre invocações locais e remotas sejam explícitas, já que as implicações são grandes. Ex.: • Corba repassa ao programa erros de comunicação como exceção; • A IDL também permite especificar o tipo de semântica que se

deseja – isso informa o projetista sobre que tipo de operação o objeto deve realizar;

• Java RMI separa invocações locais de remotas.

5.2.5 Implementação de RMI Módulo de comunicação • Executa o protocolo request-reply; • Especifica tipo de msg, requestId, referência remota; • Determina a semântica; • No servidor, seleciona o dispatcher. Módulo de referência remota • Tradução entre referências remotas e locais; • Cria referências remotas; • Mantém uma tabela de objetos remotos:

o Entradas para todos os objetos remotos relacionados ao processo;

o Entradas para cada proxy local.

5 SD Cap. 5-6 5 SD Cap. 5-6

Software RMI Camada entre objetos da aplicação e módulos de comunicação e referência remota. Função de seus componentes: • Proxy:

o Torna transparente para o cliente as invocações (comporta-se como um objeto local, mas repassa as invocações para os objetos remotos);

o Esconde detalhes da referência remota, marshalling, unmarshalling, envio e recepção de msgs;

o Um proxy para cada objeto remoto que o processo usa. • Dispatcher:

o Servidores possuem um dispatcher e um skeleton para cada classe de objetos remotos;

o Recebe requisições; methodId diz que método deve ser chamado; passa a requisição.

• Skeleton: o Implementa os métodos de uma interface; o Faz unmarshall da requisição e invoca o método

correspondente do objeto remoto; o Faz marshall do resultado (e exceções); o Passa a msg reply para o proxy para transmissão.

Métodos fábricas • Interfaces não incluem construtores; • Assim, objetos remotos não podem ser criados por invocação

remota;

• São criados na inicialização de processos ou em métodos de interfaces remotas;

• Um método fábrica é aquele que cria objetos remotos; • Objeto fábrica é aquele que possui métodos fábricas. Binder Serviço de um SD que mantém tabelas de mapeamento entre nomes de serviços e referências remotas. Permite aos servidores se registrarem e aos clientes procurar um serviço. • Corba: Corba Name Service; • Java: RMIregistry. Ativação de objetos remotos As aplicações necessitam que as informações sejam mantidas por longos períodos. Isso não justifica manter objetos em processos se eles não são necessários todo o tempo. Assim, os processos são disparados quando necessário. Um objeto remoto que pode ser invocado é chamado de ativo. Se ele não está ativo, mas pode ser ativado, é chamado de passivo. Um objeto passivo: • Implementação dos métodos; • Seu estado na forma marshalled. Processos que disparam servidores para manter objetos remotos são chamados de ativadores.

6 SD Cap. 5-6 6 SD Cap. 5-6

Armazéns de objetos persistentes Objeto persistente: pode manter seu estado e informações entre períodos de ativação. Ex.: • Serviço de objetos persistentes Corba; • Java Persistente. O processo de ativação é transparente. O estado dos objetos é salvo periodicamente em pontos íntegros para fins de tolerância a falhas. Duas abordagens para decidir se um objeto é persistente ou não: • Raízes persistentes: objetos acessíveis através de uma raiz

persistente é um objeto persistente. Ex.: Java Persistente e PerDis;

• Classes persistentes: objetos persistentes são instâncias dessas classes ou derivados delas. Ex.: Arjuna.

Alguns armazéns permitem a ativação de objetos em caches dos clientes. Ex.: PerDis e Khazana. Isso exige um protocolo de consistência de caches.

5.3 Remote Procedure Calling - RPC Programa distribuído: • Conjunto de componentes de software; • Executam sobre um número de computadores da rede.

Modelo cliente-servidor: • Uma aplicação pode ser cliente de qualquer serviço da rede; • Um servidor pode ser cliente de outros serviços; • Cada serviço possui um conjunto de operações que podem ser

invocadas pelos clientes; • A comunicação entre clientes e servidores é baseada no

protocolo requisição-resposta; • O cliente sempre espera pela resposta para continuar, mesmo que

não haja retorno de valor (pode haver erro!). RPC: • Integração entre clientes e servidores de forma conveniente; • Clientes se comunicam com servidores através da chamada de

procedimentos; • A chamada é feita no programa local; • A execução ocorre num programa remoto. Serviço ao nível RPC: • Uma interface que é exportada para os programas de um sistema; • Conjunto de funções que operam sobre certos dados ou recursos; Aspectos semânticos de RPC: • Parâmetros de entrada e saída:

• Parâmetros de entrada são passados para o servidor; • Valores enviados na requisição e copiados nas variáveis do

servidor; • Parâmetros de saída são enviados para o cliente na resposta; • Substituem as variáveis da chamada; • Parâmetros podem ser I/O.

7 SD Cap. 5-6 7 SD Cap. 5-6

• Parâmetros de entrada ~ passagem por valor • Se passagem por referência (ptr em C):

• Indicar se é I, O ou I/O; • Motivo para uma linguagem de definição de interface.

• Procedimento remoto:

• Executado em ambiente diferente de quem chama; • Não pode acessar dados do cliente (ex.: globais); • Endereços de memória do cliente não tem significado para o

servidor; Conclusão: parâmetros não podem incluir ponteiros! Referência opaca: • Referência que o cliente passa para o servidor; • Endereço do servidor; • Não tem significado para o cliente. Estruturas complexas podem ser serializadas: • Ex.: uma árvore pode ser convertida em uma expressão.

Questões de projeto Histórico: • 1981 - Xerox Courier RPC: padrão de desenvolvimento de

aplicações remotas; • 1984 - Birrel e Nelson:

• RPC para o ambiente de programação Cedar; • Datagramas sobre a Internet da Xerox; • Linguagem Mesa.

Classes de RPC: 1. o mecanismo RPC é integrado com uma linguagem específica;

• inclui uma notação de definição de interface; • ex.: Cedar, Argus, Arjuna; • pode incluir construções específicas para RPC (ex.:

exceções); 2. linguagem de definição de interfaces (pré-compilador ?!).

• ex.: SUN RPC (base do NFS); • Matchmaker (Jones e Rashid, 1986): pode ser usado com C,

Pascal, LISP, MIG (Mach Interface Generator); • Não é ligado a um ambiente particular.

Linguagem de definição de interfaces: • Especifica as características do servidor que são visíveis para o

cliente; • Nomes de procedimentos, tipos dos parâmetros; • Tipo de acesso a um parâmetro: I, O ou I/O; • O acesso indica se o valor precisa ser encapsulado na requisição

ou na resposta (marshaling); Compiladores de interfaces podem gerar descrições que podem ser usadas em diferentes linguagens, permitindo a comunicação de clientes e servidores de plataformas diferentes.

8 SD Cap. 5-6 8 SD Cap. 5-6

Tratamento de exceções: • Qualquer RPC pode falhar:

• Falha no servidor; • Sobrecarga do servidor (atraso na resposta).

• RPC deve devolver erros: • Timeouts (inerente à distribuição); • Erros de execução (FD inválido, leitura após EOF, divisão

por zero, etc.). • Erros detectados pelos procedimentos (códigos inválidos,

datas erradas, etc.). Obs.: na falta de um mecanismo de indicação de erros (como exceções em JAVA), o sistema pode usar um método bem definido de indicação de problemas (retorno de 0 ou –1 em UNIX). Garantia de entrega: Implementações possíveis do DoOperation: • Repetição da requisição: até receber uma resposta ou assumir

que o servidor falhou; • Filtro de duplicados: usado com retransmissão, para evitar

duplicação no servidor; • Retransmissão da resposta: evita a reexecução de uma

requisição. Garantia de Entrega Semântica RPC Repete Req. N S S

Filtra Duplic. - N S

Reexec/Retrans - Reexecuta Retransmite

Maybe At-least-once At-most-once

Tipos de semânticas RPC: 1. Maybe: sem tolerância a falhas. Não há garantias de que o

procedimento foi executado. Não se pode saber se o servidor executou a requisição ou se a resposta foi perdida.

2. At-least-once: o cliente é informado de que um timeout ocorreu e retransmite a requisição. Eventualmente o servidor receberá uma requisição duplicada. Se ele for projetado para executar operações idempotentes, não há problema.

3. At-most-once: o servidor filtra requisições duplicadas e retransmite as respostas.

Transparência: • O modelo Birrel e Nelson garante que a chamada a

procedimentos remotos é igual à chamada dos locais; • RPC Cedar:

• identifica os procedimentos remotos; • acrescenta o código necessário para o marshalling e

unmarshalling; • faz retransmissão da requisição após um timeout; • a duração de uma chamada é indefinida desde que o servidor

permaneça ativo. RPC é mais vulnerável do que chamadas locais: • envolve redes, outros computadores e outro processos; • consome muito mais tempo do que chamadas locais; • deve tratar erros que não acontecem nas chamadas locais.

9 SD Cap. 5-6 9 SD Cap. 5-6

Implementação O software de suporte ao RPC tem 3 funções: • Processamento da interface:

• marshalling e unmarshalling; • despacho das requisições.

• Tratamento da comunicação: • Transmitir requisições e receber as respostas;

• Binding: • Localização de um servidor para um serviço qualquer.

Processamento da interface: Requisição Cliente Servidor Chamada Marshall Send Receive Unmarsh. Executa Seleção! Retorno Unmarsh Receive Send Marshall Retorno Resposta Cada procedimento de uma interface é numerado com um número único (0, 1, 2, 3, ...). Construindo um programa cliente: • Stub:

• converte chamada local em remota; • faz o casamento dos parâmentros.

Construindo o programa servidor: • entregador (despatcher); • conjunto de stubs servidores. Compilador de interfaces: • processa as definições de uma IDL.

1. Gera os stubs do cliente; 2. Gera os stubs do servidor; 3. Gera as operações de marshall e unmarshall; 4. Fornece os cabeçalhos das funções (o corpo – o que a função

faz – deve ser fornecido pelo programador).

Binding Mapeamento de um nome para um objeto determinado (identificador de comunicação). Ex.: no Unix, um socket com número IP e Porta. Ex.: Mach, Chorus e Amoeba, uma porta independente de localização. Evita a recompilação dos clientes quando o servidor muda de porta. Se o endereço inclui a identificação do host, o cliente precisa ser recompilado toda vez que o servidor mudar de host. Num sistema distribuído, o binding é um serviço separado que mantém tabelas associando nomes de serviços com portas de servidores. Ex.: o próprio Binding, DNS, etc. Funções: • Register(serviço: string, porta: port, versão: integer); • Withdraw(serviço: string; pota: port; versão: integer); • LookUp(serviço: string; versão: integer): port.

10 SD Cap. 5-6 10 SD Cap. 5-6

Quando um servidor inicia seus serviços, ele envia uma mensagem para o Binding para se registrar. Quando ele encerra suas atividades, ele pede para ser retirado das tabelas do Binding. Quando um cliente quer usar um serviço, manda uma mensagem ao Binding para descobrir o endereço do servidor. Se o servidor falha, o cliente pode requisitar ao Binding a porta de outro servidor do mesmo serviço. Se o sistema usa portas independentes de localização, um servidor pode se mover para outro host sem informar o Binding. Os clientes não são afetados pela mudança. Se o identificador de porta inclui o host, o Binding deve ser informado toda vez que o servidor for movido. Os clientes vão ter requisições ignoradas. Eles devem contatar o Binding para descobrir o novo endereço do serviço. Serviço único: todos os outros dependem dele: • Tolerante a falhas (ex.: salvando as tabelas em arquivos toda vez

que elas são alteradas); Um sistema distribuído dependente de um único Binder não é escalável: • As tabelas podem ser particionadas (maior desempenho); • Também podem ser replicadas em um grupo de Binders

(tolerância a falhas).

Alguns serviços são representados por múltiplos servidores, cada um rodando em um host diferente: • Cada um deles é uma instância de um serviço; • Um Binder deve ser capaz de registrar as várias instâncias de um

serviço; • Se o Binder não usa a instância de um serviço, o cliente deve

informar qual delas ele quer usar (número seqüencial); • Numa falha, o cliente pega a próxima instância.

• Se o Binder usar a instância, ele pode distribuir os clientes pelas diversas instâncias de um serviço (balanceamento de carga)

Exportação: registro de um nome de interface associado com a porta de um servidor. Importação: pergunta ao Binder pelo nome de um serviço retornando um número de porta. Localização do Binder: • Endereço bem definido, compilado em todos os clientes;

• Clientes e servidores precisam ser recompilados se o Binder for mudado;

• O Kernel informa o endereço do Binder (ex.: variável de ambiente). Permite a relocação ocasional do Binder;

• Quando clientes ou servidores iniciam, mandam mensagens de broadcast para localizar o Binder (ex.: no Unix, o Binder fica numa porta bem conhecida. Num broadcast, o Binder que receber informa qual é o seu host).

11 SD Cap. 5-6 11 SD Cap. 5-6

RPC Assíncrono Ex.: sistema de janelas X-11 Utiliza uma forma assíncrona de RPC: X-11 é um servidor de janelas; As aplicações que querem mostrar alguma coisa na tela (texto,

gráficos, etc.) são os clientes. Características: Para gerar ou atualizar a informação de uma janela, o cliente

envia várias requisições ao servidor, cada uma delas com uma pequena quantidade de informações: Strings, troca de fonte, um caracter.

O cliente não recebe respostas para suas requisições; Cliente e servidor trabalham em paralelo; Algumas requisições podem exigir intensa computação - há

ganhos em realizá-las enquanto o servidor atende requisições anteriores;

O servidor pode manipular requisições de vários clientes; Ou mesmo de dispositivos; O servidor tem uma performance melhor se ele não precisa

enviar respostas para as requisições. RPC sem respostas e sem bloqueio é chamado de assíncrono. Comparação: • No RPC síncrono, não existe paralelismo; • No RPC assíncrono, o cliente faz todas as requisições de que

necessita; só então espera pelos resultados;

• A espera no lado do cliente se resume ao intervalo entre a última requisição e a recepção da primeira resposta;

• Se não houver necessidade de resposta às requisições, o tempo de espera não existe.

Otimização possível: • Armazenar as requisições no lado do servidor até que ocorra um

timeout ou que o cliente peça uma resposta; • Só então as requisições são enviadas como uma comunicação só; • Isto reduz a latência de rede.

Requisições paralelas para vários servidores Ex.: considere um banco com vários servidores, cada um responsável por registrar os lançamentos feitos em uma agência. • Para saber o saldo de uma conta, é preciso consultar os

lançamentos de todas as agências; RPC síncrono: • O cliente faz requisições para um servidor de cada vez,

esperando a resposta; • Só após chegar uma resposta, ele manda a requisição para o

próximo. RPC assíncrono: • O cliente envia as requisições para todos os servidores em

seqüência e depois espera por todas as respostas; • Os servidores trabalham em paralelo. Comparação entre RPC síncrono e assíncrono:

12 SD Cap. 5-6 12 SD Cap. 5-6

RPC síncrono argumentos marshall send receive unmarshall transmissão executa marshall send receive unmarshall processa argumentos marshall send receive unmarshall executa marshall send receive unmarshall processa Cliente Servidor

RPC assíncrono argumentos marshall send argumentos marshall send receive unmarshall executa marshall send receive receive unmarshall unmarshall executa processa marshall send receive unmarshall processa Cliente Servidor

13 SD Cap. 5-6 13 SD Cap. 5-6

RPC assíncrono no sistema Mercury Otimizações necessárias no paradigma RPC:

• Se não há necessidade de resposta, o cliente pode fazer um RPC e continuar sua execução;

• Se não há necessidade de resposta, várias requisições podem ser armazenadas e enviadas no mesmo send;

• Se há necessidade de resposta, o cliente pode processar até que ela seja necessária para só então requisitá-la.

Sistema Mercury – MIT, 1988: • Call-stream: combina RPC síncronos e assíncronos; • As diferenças nos métodos de comunicação não são visíveis para

os servidores: • Eles só recebem requisições e devolvem respostas.

• Simplifica o projeto dos servidores; • O cliente determina o método que vai utilizar; • Diferente de outros sistemas onde a interface define o método e

o servidor precisa ser projetado de acordo; • Se o cliente não precisa da resposta a uma requisição, o call-

stream não a devolve para o cliente.

Promessas • Liskov e Shrira, 1988; • Uma promessa é criada no momento de uma chamada a um

servidor; • Pode assumir dois estados possíveis:

• Bloqueado; • Pronto.

• Quando criada, a promessa fica no estado bloqueado; • Uma promessa é associada com uma requisição específica; • Quando chega a resposta a essa requisição, ela é armazenada na

promessa correspondente; • Neste caso, o estado da promessa passa para pronto; Funções: • claim(): extrai a resposta de uma promessa;

• se ela estiver no estado bloqueado, o cliente bloqueia até que a promessa passe para o estado de pronto ou que ocorra uma exceção.

• ready(): testa o estado de uma promessa.

5.4 Eventos e notificações • Objetos que geram eventos numa plataforma distribuída

publicam os eventos disponíveis para observação por outros objetos;

• Objetos que querem receber notificações de eventos publicados assinam tipos de eventos em que têm interesse;

• Objetos que representam eventos são chamados de notificações. Sistemas baseados em eventos têm 2 características principais: • Heterogêneos: permite que objetos não projetados para

interoperação trabalhem em conjunto. Um sistema de eventos que permite publicação e assinatura pode permitir trabalho conjunto para objetos que não foram projetados com esse fim;

14 SD Cap. 5-6 14 SD Cap. 5-6

• Assíncronos: permite notificação de eventos aos assinantes sem necessidade de sincronismo, o que significa bloqueio dos envolvidos.

5.4.1 Participantes em notificações de eventos distribuídos Arquitetura que permite independência entre autores e assinantes: • Banco de dados com eventos publicados e interesse dos

assinantes; • Quando ocorre um evento que possui interessados, uma

notificação é enviada. Participantes: • Objetos de interesse: aqueles que possuem métodos que podem

alterar estados – isso gera eventos que podem ter interessados; • Evento: ocorre como resultado da execução de um método; • Notificação: objeto que contém informações sobre um evento: • Assinante: assina algum tipo de evento em outro objeto – recebe

notificações dele; • Observadores: objetos que isolam autores de assinantes. Eles

monitoram os eventos e notificam aqueles assinados; • Autor: objeto que declara que vai gerar notificações de certos

tipos de eventos. Pode ser um objeto de interesse ou um observador.

Possíveis casos de comportamento em um serviço de eventos:

• Objetos de Interesse enviam notificações diretamente aos assinantes;

• OdI enviam notificações via observadores aos assinantes; • OdI fora do serviço de eventos. Observadores fazem consultas ao

OdI para descobrir quando ocorre um evento. Ele é notificado aos assinantes.

Papéis dos observadores • Encaminhar notificações para os assinantes de um ou + objetos

de interesse. São os objetos de interesse que informam os observadores sobre seus assinantes;

• Filtros de notificações: aplicados pelos observadores para reduzir a quantidade de notificações. São baseados em regras informadas pelos assinantes. Ex.: num banco, retiradas, mas apenas as maiores que 10000,00;

• Padrões de eventos: relação de eventos entre si. Ex.: num banco, quero ser informado sempre que houver 3 retiradas sem um depósito;

• Caixas de correio para notificações: usadas para encaminhar notificações sem que o assinante receba na hora. Ex.: ele não possui uma conexão permanente, ou tornou-se passivo. As notificações são recuperadas mais tarde.

15 SD Cap. 5-6 15 SD Cap. 5-6

Cap. 6 – Suporte dos Sistemas Operacionais

6.1 Introdução Função importantes de um SD: compartilhamento de recursos. • Clientes invocam operações sobre recursos em outros nós ou

outros processos. Middleware: permite a interação entre aplicações clientes e recursos (gerentes). • O SO fica abaixo do middleware; • O que importa aqui é o relacionamento entre os dois; • Como o SO permite ao middleware o acesso aos recursos físicos,

como ele implementa políticas de acesso, etc. Abstrações: • SO fornece modelos para manipular certos recursos; • Ex.: arquivos x blocos de disco; • Ex.: sockets x fluxo de redes. Num SO de rede (Unix, NT, etc.), o usuário que precisa executar um programa numa máquina diferente precisa se envolver: • Telnet, fornece senha, executa o programa. SO Distribuído:

• O usuário não se preocupa com o nó em que seu programa executa;

• Não importa onde estão os recursos; • O usuário vê uma única imagem do sistema; • A esolha de um nó para executar um programa depende da

política de escalonamento. Caracterização de um SOD: • Permite a programação de um SD, permitindo a implementação

de uma grande gama de aplicações; • Apresenta para as aplicações abstrações genéricas e orientadas

aos problemas dos recursos do sistema; • Num SD aberto, o SOD é implementado como um conjunto de

kernels e servidores. • Não há uma distinção clara entre os serviços do sistema e as

aplicações que rodam no topo do SOD. Exemplos: Mach e Chorus. • Resultados de grandes períodos de pesquisa nos anos 80 e 90; • Alto nível de interesse técnico e comercial; Outros exemplos técnicos: • Amoeba, Clouds, V System; • Não aceitos para uso geral; Todos esses projetos empregam microkernel. SOD: • Infraestrutura de gerenciamento genérico de recursos e

transparente em rede;

16 SD Cap. 5-6 16 SD Cap. 5-6

• Recursos de baixo nível: processadores, memória, placas de rede, periféricos em geral;

• Plataforma para recursos de alto nível: planilhas, troca de mensagens eletrônicas, janelas;

• Oferecidos aos clientes pelos serviços do sistema; Acesso aos recursos pelo sistema: • Feito de forma transparente; • Identificadores independentes de localização; • Uso das mesmas propriedades; • Transparência fornecida no nível mais baixo, para que não

precise ser feita em cada serviço; Um SOD deve fornecer ferramentas para encapsular recursos: • De forma modular; • Modo protegido; • Amplo acesso via rede. Encapsulamento de recursos: • Interface padronizada – implementação escondida do usuário; • Concorrência – recursos compartilhados por vários usuários; • Proteção – segurança contra acesso ilegítimo. Os clientes acessam os recursos através da passagem de identificadores como argumentos: • Em system calls para o kernel; • RPC para um servidor. Invocação: acesso a um recurso encapsulado.

Tarefas relacionadas com a invocação de recursos: • Resolução de nomes – localização; • Comunicação para acesso aos recursos; Escalonamento: processamento das invocações no kernel. Middleware x SOs de rede • Não há SOs distribuídos em uso corrente hoje; • Apenas SOs de rede (Unix, NT, MacOS, etc.); • Motivos:

o Usuários se preocupam com suas aplicações de uso comum;

o Não trocam seus SOs por melhor que seja um outro produto se não puderem executar suas aplicações;

o Usuários preferem ter um certo controle sobre suas máquinas;

o A idéia de entregar os recursos a outros usuários sem controle é estranha.

Por outro lado, o uso de um middleware com um SO de rede é + versátil e aceitável: • O usuário consegue rodar seus programas favoritos; • Ele tem controle sobre os recursos de sua máquina; • Os usuários remotos têm um certo grau de transparência no

acesso aos recursos da rede; • É possível acessar recursos compartilhados com um certo grau

de concorrência.

17 SD Cap. 5-6 17 SD Cap. 5-6

6.2 Camada de sistema operacional

Aplicações, serviços

Middleware

OS1 Processos, threads, comunicação, etc.

OS2 Processos, threads, comunicação, etc.

Hardware do computador e rede

Hardware do computador e rede

Nó 1

Nó 2 As interfaces apresentadas por kernels e servidores devem apresentar pelo menos o seguinte: • Encapsulamento: conjunto mínimo de operações fornecidas aos

clientes. Detalhes de implementação escondidos; • Proteção: evita acessos indevidos; • Concorrência: clientes devem acessar os recursos de forma

concorrente. Isso deve ser transparente para eles.

Kernel Kernels e proteção: • O Kernel executa com privilégio de acesso total;

• Ex.: pode controlar a unidade de MM; • Pode conceder privilégio de acesso a recursos físicos; • Determina o espaço de endereçamento:

• Permite que os processos se protejam uns dos outros; • Evita que um processo invada áreas indevidas.

• Modo supervisor e usuário: • Processos usuários podem rodar em modo supervisor quando

tem acesso direto a um dispositivo; • System call trap: mecanismo de invocação de recursos

gerenciados pelo kernel; Kernel monolítico e microkernel – um SOD aberto deve permitir: • Executar apenas o suficiente para tornar o ambiente operacional

(módulos supérfluos gastam recursos); • Alterações no software ou sistema que implementa um serviço,

independentemente de outros elementos; • Alternativas do mesmo serviço para atender usuários ou

aplicações diferentes; • Introdução de novos serviços sem prejudicar os existentes. Um certo grau de abertura é obtido com a utilização de kernels tradicionais como base. Ex.: o DCE da OSF usa Unix, VMS, OS/2, etc. • Permitem a execução de processos servidores; • Suportam protocolos (ex.: RPC); • Possuem binding e serviços de nomes; • Serviços de tempo (sincronização); • Segurança; • Threads.

18 SD Cap. 5-6 18 SD Cap. 5-6

Unix: • Monolítico; • Sugere um sistema massivo; • Executa todas as operações básicas do sistema; • 1 MB de código e dados; • Não diferenciável: codificado de forma não modular; • Intratável: a alteração de um módulo para adequação a novos

requisitos é muito difícil.

Carregado dinamicamente

Kernel monolítico MicroKernel Principais funções de um microkernel: • Processos; • Memória; • IPC; • Todos os outros serviços carregados dinamicamente em

servidores específicos; • Um serviço extra só é carregado na máquina que precisa dele; • Acesso via invocação (RPC). O microkernel na hierarquia de um sistema:

Comparação: • Abertura; • Modularidade; • Um kernel pequeno tem mais chances de ter menos bugs; • Mais fácil de manter; • Kernel monolítico é mais difícil de ser modular; • Impossível extrair um módulo para execução remota; • Um bug num módulo pode se espalhar para os demais; • Alterar um módulo implica em recompilar o kernel e reiniciá-lo; • Vantagem: eficiência para realizar as tarefas.

Arquitetura de um microkernel Em princípio, não há uma definição clara de quais módulos um microkernel deve ter. Todos os produtos dessa categoria incluem: Gerência de processos; Gerência de memória;

Sn

S1 S2 S3 S3S2S1

Microkernel

Hardware

Serviços abertos processos/objetos das aplicações

Suporte de linguagem

Suporte de linguagem

Emulação de OS

19 SD Cap. 5-6 19 SD Cap. 5-6

Passagem de mensagens local. Tamanho: 10 KB até várias centenas de KB de código e dados

estáticos. Microkernels são projetados para serem portáveis: A maior parte de seu código é escrito em linguagem de alto nível

(C, C++, etc.); Recursos físicos são agrupados em camadas; Componentes dependentes de máquina são reduzidos:

Manipulação do processador, unidade de gerência de memória, registradores da unidade de ponto flutuante;

Tratamento de interrupções; Traps; Exceções.

A arquitetura de um microkernel geral pode ser visto na figura:

Aplicações Hardware

Gerente de processos: criação, interface, etc. Gerente de Threads: criação, sincronização, escalonamento.

Processadores disponíveis. Política de escalonamento a critério do usuário.

Gerente de comunicação: IPC. Gerente de memória: memória física, MMU, caches. Supervisor: tratamento de interrupções, system calls, exceções.

6.4 Processos e threads Unix: 1 processo, 1 atividade de processamento (1980). Processo: recurso caro para criar e manter. O compartilhamento entre atividades relacionadas é caro e complexo. Solução: generalização do conceito de processo. Associar mais de uma atividade ao mesmo processo. Processo: ambiente de execução + 1 ou mais threads. Thread: abstração de atividade do sistema operacional. "Thread of execution".

Ambiente de execução: unidade de gerenciamento de recursos. Coleção de recursos gerenciados pelo kernel local, aos quais suas

threads têm acesso; Ambiente de execução: Espaço de endereçamento; Sincronização de threads e IPC, como semáforos; interfaces de

comunicação (portas); Recursos de alto nível (arquivos, janelas, etc.).

Gerente de Processos

Supervisor

Gerente de Threads

Gerente de Memória

Gerente de

Comunicações

20 SD Cap. 5-6 20 SD Cap. 5-6

Obs.: num microkernel, recursos de alto nível como arquivos e janelas não fazem parte dos recursos de um ambiente de execução. São acessados via servidores. Ambientes de execução são caros e difíceis de criar; Várias threads podem compartilhar o mesmo ambiente; Threads podem ser criadas e destruídas dinamicamente; Objetivo: maximizar o grau de concorrência entre operações

relacionadas. Threads: lightweight process.

6.4.1 Espaços de endereçamento • Os espaços não são contíguos. • Gaps permitem o crescimento das regiões. • Componente mais caro de um ambiente de execução; • Grande (232 é um valor típico); • Consiste de uma ou mais regiões; • Região: área contígua de memória virtual acessível pelas threads

do processo; Regiões não se sobrepõem; Propriedades das regiões: • Extensão: endereço mais baixo e tamanho; • Permissões para as threads: read/write/execute; • Direção de crescimento: para cima ou para baixo; Analogia para processos e threads:

• Um ambiente de execução consiste de um jarro com água e comida;

• A 1ª thread desse processo é uma mosca dentro do jarro; • A mosca pode gerar filhos (outras threads) ou matá-los; • As moscas podem consumir a água e/ou a comida; 2N Memória Gaps Virtual (ex.: 232) 0

♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦

Regiões Auxiliares

♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦

♦♦♦♦♦♦♦♦Stack♦♦♦♦♦♦♦♦

♦♦♦♦♦♦♦♦Heap♦♦♦♦♦♦♦♦

♦♦♦♦♦♦♦♦♦Text♦♦♦♦♦♦♦♦

21 SD Cap. 5-6 21 SD Cap. 5-6

• Uma mosca não pode sair de seu jarro para entrar em outros jarros;

• As moscas podem colidir, quando resultados imprevisíveis poderão ocorrer;

• As moscas podem consumir toda a água e comida – o ambiente passa a ser inviável.

O sistema com um número indefinido de regiões permite o mapeamento de arquivos no espaço de endereçamento: • Um arquivo mapeado é acessado como um array de bytes; • O sistema VM garante que as atualizações se reflitam no sistema

de arquivos.

6.4.2 Criação de um novo processo Unix: • Um processo que chama o comando fork() cria um novo

processo copiando o seu espaço de endereçamento; • A diferença é o valor retornado pelo fork(); • O comando exec() transforma o programa que chama num

processo do arquivo em disco passado como parâmetro. Num SD, há duas novas considerações: • Múltiplos computadores; • A infraestrutura de suporte reside em serviços separados. Aspectos de criação de processos em um SD: • Escolha do host alvo (onde o novo processo vai residir); • Criação de um ambiente de execução;

• Criação de uma thread, com um ponteiro de pilha default e um contador de instruções.

Escolha de um host alvo Depende do sistema: • V System: executa um processo num host determinado ou no

mais ocioso; • Amoeba: escolhe um dos processadores do pool onde o processo

vai residir. É transparente. Depende da necessidade. Se é necessário trabalhar com paralelismo explícito, pode ser necessário indicar hosts específicos. Tipos de políticas: • Política de transferência: diz se um novo processo é local ou é

executado num host remoto. Depende da carga; • Política de localização: determina o host remoto que recebe um

novo processo; o Depende da carga, da arquitetura e de possíveis recursos

especializados que o host tem. As políticas podem ser estáticas ou adaptativas: • Estáticas não consideram o estado atual do sistema;

o Podem ser deterministas (a transferência sempre ocorre de A para B);

o Ou probabilísticas (a transferência ocorre de A para um entre B-E – escolha aleatória).

• Adaptativas: usam heurísticas sobre fatores momentâneos.

22 SD Cap. 5-6 22 SD Cap. 5-6

Sistemas de carga compartilhada: • Centralizados: um gerente de carga para o sistema; • Hierárquicos: vários gerentes, organizados em árvore; • Decentralizados: todos são gerentes. Tipos de algoritmos de carga compartilhada: • Iniciados pelo transmissor: disparado quando a carga local

atinge um limite máximo; • Iniciados pelo receptor: quando a carga local cai abaixo de um

certo valor, o nó avisa os demais que passou a ser um receptor de carga.

Sistemas migratórios: a carga pode ser distribuída a qualquer momento: • Recurso pouco usado; • O custo para transferir um processo é muito alto; • Extrair o estado de um processo do kernel é muito difícil. Criação de um novo ambiente de execução Opções: • O sistema inicia um espaço de endereçamento genérico, baseado

em certos parâmetros que ele possui: tamanho da área de código, stack, etc.

• Geração a partir de um já existente: fork() • Pai e filho compartilham a área de código! • Isto é feito pelo mapeamento da região de texto do pai dentro

do espaço de endereçamento do filho. • Stack e heap são copiados do pai para o filho.

• Mach e Chorus: usam copy-on-write: • Regiões herdadas do pai são copiadas apenas logicamente; • A cópia física só ocorre quando um dos processos tenta

escrever sobre a região: • O compartilhamento é desfeito; • Ocorre a cópia física; • Esta cópia pode acontecer em disco, caso ocorra um page

fault. Obs.: herança é um problema caso haja uma ou mais portas em uso pelo processo pai. Dois processos não podem compartilhar fluxos de mensagens.

6.4.3 Threads Considere um servidor com uma ou mais threads. Assumimos que uma requisição qualquer utiliza 2 msegs de tratamento e 8 msegs de I/O (sem o uso de cache). O computador possui apenas um processador. Máximo throughput dependendo do número de threads: • 1: 2 + 8 = 10 msegs. 100 requisições por segundo. • 2: uma thread pode processar enquanto a outra está esperando. As threads de um processo não podem fazer I/O em paralelo. Assim, todos os I/Os devem ser feitos seqüencialmente. Se todas as requisições de I/O forem serializadas, temos 1000/8 = 125 requisições por segundo.

23 SD Cap. 5-6 23 SD Cap. 5-6

Considere agora um cache de blocos de disco. O servidor mantém blocos em buffers em seu espaço de endereçamento. Se há uma requisição, ele 1º verifica se o bloco está no cache. Se estiver, a requisição é atendida com I/O zero. Considerando uma taxa de acerto de 75%, Tempo médio por requisição = 0,25 * 8 + 0,75 * 0 = 2 msegs. Máximo throughput = 500 requisições por segundo. Entretanto, há um acréscimo de tempo pela pesquisa no cache. Vamos supor que o tempo médio por requisição real seja de 2,5 msegs. Máximo throughput = 400 requisições por segundo. Arquiteturas para servidores multi-thread Pool de trabalhadores: • O servidor mantém um pool de trabalhadores para processar as

requisições; • Em geral, uma thread de I/O recebe as msgs através de várias

conexões; • As requisições são colocadas em filas para tratamento. Threads-por-requisição: • A thread de I/O cria uma thread para cada requisição que chega; • Ela se destrói quando a tarefa está feita; • Maximiza o I/O; • Custo de criação e destruição de threads.

Threads-por-conexão: • O servidor coloca uma thread para cada conexão de cliente; • Em uma conexão, cada cliente pode fazer várias requisições. Threads-por-objeto: • Uma thread associada a cada objeto remoto; • Cada objeto possui sua fila. Threads nos clientes Nos clientes, o uso de threads é interessante para evitar bloqueios indesejáveis em certas operações: • Em requisições a um servidor; • Em RMI (ou RPC), quando se faz invocação a um objeto

remoto. Formas organização de threads nos clientes: • Por requisição: para cada requisição feita no cliente é disparada

uma thread que gerencia o processo; • Por conexão: cada conexão estabelecida com um servidor

remoto recebe uma thread – toda comunicação nessa conexão é feita por meio dela;

• Por objeto: para cada objeto remoto usado pelo cliente é disparada uma thread – cada uma faz as invocações remotas para o seu objeto.

Threads x múltiplos processos A mesma sobreposição pode ser alcançada por múltiplos processos. Por que um sistema multithread é preferível?

24 SD Cap. 5-6 24 SD Cap. 5-6

Ambiente de execução (processo): • Espaço de endereçamento; • Portas, interfaces de comunicação, etc. • Semáforos, objetos de sincronização, etc. • Lista de threads. Thread: • Registradores salvos; • Estado (ex.: bloqueado) e prioridade; • Informação sobre tratamento de interrupções. Elementos comuns entre processos e threads: • Páginas residentes em memória; • Entradas de caches. Sumário: • Criar uma nova thread para um processo já existente é mais

barato do que criar um novo processo; • Chavear para outra thread de um processo é mais barato do que

para threads de processos diferentes; • O compartilhamento dos recursos de um processo por suas

threads é mais simples do que por processos separados; • O problema é que as threads não têm proteção uma das outras. Custo de criação de uma thread: Alocação da região da pilha; Valores iniciais para os registradores; Estado inicial: SUSPENDED ou RUNNABLE; Prioridade; Acréscimo de identificador no registro de threads.

Comparação de tempos: Sistema Unix; Arquitetura CVAX; Kernel Topaz; Anderson et al., 1991; Teste: processo ou thread criados para fazer uma chamada nula; Processo: 11 msegs; Thread: 1 mseg.

Memória: Um processo recebe page faults logo que inicia sua execução; Uma thread também! Entretanto, threads podem se beneficiar dos acessos feitos sobre

suas áreas por outras threads; Pode aproveitar áreas colocadas nos caches por outras threads.

Programação de Threads A programação de threads é Programação Concorrente! Conceitos desta seção: race conditions, seção crítica, variáveis de condição e semáforos. Ex.: Modula-3, Java: suporte direto à threads; C: extensão por biblioteca; P Threads: padrão de threads para o Posix desenvolvido pelo

IEEE; GNU Threads: padrão da Free Software Foundation para o

SunOS.

25 SD Cap. 5-6 25 SD Cap. 5-6

Chamadas Java para manipulação de Threads: • Thread(ThreadGroup grupo, Runnable alvo, String nome) – cria

uma nova thread no estado SUSPENDED, que pertence a grupo e é identificada como nome; passa a executar pela chamada do método run() de alvo.

• setPriority(int newPriority), getPriority() – muda ou retorna a prioridade da thread.

• Run() – executa o método run() de seu objeto alvo, se houver; ou seu próprio método run() (Thread implementa Runnable).

• start() – muda o estado da thread de SUSPENDED para RUNNABLE.

• sleep(int millisecs) – a thread passa para o estado SUSPENDED pelo tempo especificado.

• yield() – passa para o estado READY e chama o escalonador. • destroy() – destrói a thread. Obs.: • Grupos são isolados uns dos outros, no sentido de que não

podem ser gerenciados entre si; • Threads de um grupo não podem criar threads de outro; • Grupos podem ter prioridades limites estabelecidas pelo

processo. Chamadas da biblioteca C Threads: threadId = cthread_fork(func, arg) - permite criar uma thread a

partir de outra, que executa a função func passando um só argumento arg;

cthread_exit(result) - termina a thread atual; cthread_join(threadId) - a thread que criou threadId espera até o

seu término;

cthread_set_data(threadId, data) - associa dados globais exclusivamente com uma thread;

cthread_data(threadId) - libera os dados associados a uma thread;

cthread_yield() - permite que outra thread rode. Problemas com Threads: <stdio.h> em C; 1 buffer para cada stream de I/O (ex.: vídeo) o problema ocorre quando mais de uma thread tenta mandar

caracteres para um terminal; a ordem depende do escalonador; a biblioteca mantém um ponteiro para a posição no buffer onde o

próximo caracter deve ser colocado: pode levar a race conditions.

Chamadas de sincronização da biblioteca C Threads: mutex_lock(mutexId) mutex_unlock(mutexId) condition_wait(conditionId, mutexId) condition_signal(conditionId)

Escalonamento de Threads Preemptivo: uma thread pode ser suspensa pelo escalonador para

que outra execute; Não preemptivo (corrotina): uma thread executa até fazer uma

chamada que cause sua suspensão. Corrotinas:

26 SD Cap. 5-6 26 SD Cap. 5-6

Qualquer seção que não apresenta chamadas é uma seção crítica; Só servem para máquinas com 1 processador; Não servem para Real Time; Aplicações processor bound devem dar chances às outras (yield).

Implementação de Threads Alguns kernels permitem processos com apenas uma thread; Porém, há bibliotecas que permitem implementar processos

multithreads. Ex.: SunOS 4.1 Lightweight Processes (pacote) O kernel não reconhece as threads; Não há escalonamento de threads independentemente; Se alguém (o processo ou uma thread) faz uma sys call

bloqueante, todos bloqueiam; As threads de um processo nessas condições não podem executar

num sistema multiprocessador; A troca de contexto de threads dentro de um processo não

precisa ser feita via sys call; O escalonamento pode ser específico da aplicação;

Psyche (SO multiprocessador) - processador virtual (PV): Um PV é um recurso pertencente a um processo; Implementado no kernel; Associado com processadores reais; O processo controla esses recursos diretamente; Cada um executa uma função; O kernel informa o processo dos eventos; O processo pode trocar uma thread bloqueada em um PV; Ou pode trocar o PV de um processador real.

6.4 Nomes e proteção Um serviço em geral gerencia vários recursos: Cada um deles pode ser acessado independentemente pelos

clientes; Para esta finalidade, o serviço fornece identificadores para cada

um dos seus recursos; Serviços precisam ser reconfiguráveis - flexíveis:

Para um grupo de servidores gerenciar um recurso individual;

Para se localizar os servidores. Clientes acessam recursos através de requisições a um serviço, passando o identificador correto. Requisições são passadas a identificadores de comunicação, que

podem ser obtidos de um serviço de binding; Mach e Amoeba: portas; Chorus: grupos de portas.

Identificação de um recurso – deve-se fornecer: Porta (grupo) de acesso ao servidor que gerencia o recurso; Identificador específico.

• Identificadores independentes de localização fornecem

transparência de rede; • O formato dos identificadores é escolhido por quem implementa

o serviço; • É boa prática usar o mesmo formato para a mesma família de

serviços; • Facilita a administração e marshalling;

27 SD Cap. 5-6 27 SD Cap. 5-6

• Identificadores devem ser únicos num SD inteiro ou, ao menos, dentro de um serviço;

• Amoeba: identificadores únicos em todo o SD; • Permite usar um identificador sem saber de que serviço ele é!

Reconfigurabilidade Capacidade de um SD de se adaptar à evolução ou mudanças em suas condições, tais como carga de rede ou falhas: • Relocação de servidores: ocorre pela criação de novas instâncias

de servidores ou por migração; • Mobilidade de recursos: recursos migram de um servidor para

outro no mesmo serviço. • É preciso manter as transparências de localização e de migração; • Problema: como reconfigurar o serviço on-line?

Proteção de recursos Objetivo: garantir que os processos só possam acessar os recursos para os quais tenham permissão. Problemas: • As redes devem ter abertura; • Os computadores de um SD podem sofrer ataques que alterem

seu software; • A proteção deve ser específica por serviço; • Os servidores podem receber qualquer requisição de qualquer

computador/processo da rede;

Domínios de proteção • Já visto em SO I; • Conjunto de pares (recurso, direitos), relacionando todos os

recursos que podem ser acessados pelos processos que rodam nesse domínio;

Ex.: Unix – domínio determinado pelo grupo e usuário. Os direitos são determinados pelas operações RWX. Implementações: • Capabilities e Listas de controle de acesso.

6.5 Comunicação e invocação Formas de comunicação: • Produtor-consumidor; • Cliente-servidor; • Comunicação de grupo. Formas de qualidade de serviço: • Garantia de entrega; • Banda de transmissão; • Latência; • Segurança. Questões relacionadas aos serviços de comunicação: • Primitivas disponíveis;

28 SD Cap. 5-6 28 SD Cap. 5-6

• Garantias de QoS; • Protocolos; • Abertura da implementação; • Procedimentos para aumentar a eficiência.

Primitivas de comunicação Formas de passagem de mensagens: • Send-receive; • DoOperation-GetRequest-SendReply. A implementação depende dos recursos disponíveis: • As primitivas podem ser confiáveis; • Se não forem, isso pode ser alcançado em níveis mais altos; • Uma das formas pode ser implementada usando a outra; • Isso pode ser feito em baixo nível (kernel) ou em alto nível (até

na aplicação).

Compartilhamento de memória • Comunicação local deve ser feita pela transferência do conteúdo

de áreas de memória entre os processos; • Feito pelo kernel através de operações especiais (Copy-on-

write); • Transfere dados de páginas de um espaço de endereçamento para

páginas de outro; • Regiões compartilhadas podem ser usadas para facilitar (dar

mais velocidade) a comunicação processo-kernel e/ou processo-processo;

• Problemas:

• Sincronismo; • Justifica se for bastante usado, já que o custo para estabelecer

é alto. Qualidade de Serviço O que é possível fazer com primitivas não confiáveis?

É possível construir uma versão confiável de um Send; Até um RPC com semântica at-least-once ou mesmo at-most-

once; Comunicação orientada a streams, com um sistema apropriado

de buffers; Multicast de alto nível; Segurança para a comunicação, passando por um serviço de

criptografia; Principal dificuldade é latência satisfatória: Há serviços que precisam de mais latência do que outros; Multimídia impõem restrições de tempo real; O SO deve atender as solicitações de um mínimo de qualidade

dos usuários ou recusar o serviço; Protocolos e abertura Alguns sistemas incorporam seus próprios protocolos:

Ex.: Amoeba - Amoeba RPC; V system - VMTP; Sprite - Sprite RPC.

Problema: esses protocolos não são usados em ambientes de uso geral;

29 SD Cap. 5-6 29 SD Cap. 5-6

TCP, UDP e IP não suportam RPC diretamente; Mach e Chorus têm outra estratégia:

Suportam apenas passagem de mensagens local; Usam servidores no topo do kernel para tratar os protocolos

de rede; Sistema aberto, já que qualquer um pode implementar seu

próprio servidor. Desempenho de Invocação Mecanismos de invocação: • Chamar um procedimento local; • System call; • Enviar uma mensagem; • RPC; • Chamar um método de um objeto, etc. Em todos os casos, código é executado fora dos limites de quem chama. É preciso passar argumentos e retornar dados para quem chama.

Tipos de operações entre espaços de endereçamento: Thread User kernel Thread 1 Thread 2 User 1 Kernel User 2 Thread 1 Thread 2 Rede User 1 Kernel 1 Kernel 2 User 2 Tipos de operação: • Síncronas: chamada local e RPC; • Assíncronas: operação sem retorno de valores. Desempenho de RPC RPC nulo: RPC sem parâmetros, que executa um procedimento nulo e não retorna valores. • Melhor tempo reportado para um RPC nulo entre 2 processos

usuários através de uma LAN: 1 milisegundo! • Uma chamada local de procedimento é executada numa fração

pequena deste tempo.

trap

Instruções privilegiadas

System Call

RPC (no mesmo computador

RPC (entre computadores)

30 SD Cap. 5-6 30 SD Cap. 5-6

• Um RPC nulo transfere cerca de 100 bytes, somando dados de cabeçalhos de pacotes de rede.

• A 100 Mbits/seg., o tempo total de rede para transferir essa quantidade é cerca de 0,1 milisegundos.

• A maioria do tempo é composta de atrasos impostos pelo SO e pelo código do RPC no nível do usuário.

Estudo sobre a média de RPCs chamados (Bershad, 1990 – 1,5 milhão de chamadas): • A chamada mais freqüente é de menos de 50 bytes do usuário; • A maioria das chamadas transfere menos que 200 bytes; • RPC que transfere blocos de disco tende a ter 1-8 kb; • O uso de caches tende a diminuir a freqüência dessas chamadas. A maioria das chamadas RPC cabe num pacote de rede (em torno de 1 KB). Um RPC nulo representa o overhead fixo que uma chamada apresenta. Figura 6.14: • O atraso de um RCP cresce proporcionalmente ao tamanho do

pacote; • Há um salto toda vez que é preciso acrescentar mais um pacote

na chamada. Throughput: • O atraso não é o único elemento de interesse no RPC; • Throughput: taxa na qual os dados podem ser transferidos entre

computadores;

• Na fig. 6.14, o throughput é pequeno para pequenas quantidades de dados;

• À medida que cresce a quantidade de dados, cresce o throughput, já que o overhead fixo torna-se menos significativo;

• Hutchinson, 1989 – máximo throughput = 750 KB/seg. (Ethernet 10 Mbits/seg!);

• O throughput para quantidades maiores de dados deve aumentar bastante com redes de 100 Mbits/seg (ou mais)!

• Mesmo assim, para quantidades pequenas o overhead fixo deve predominar;

Quais são esses overheads e o que fazer para minimizá-los? Passos de um RPC: • Stub do cliente:

• Marshalling dos argumentos; • Envio da requisição; • Recepção da resposta; • Unmarshalling da resposta.

• Servidor: • Dispatcher recebe a requisição; • Chama o stub apropriado do servidor.

• Stub do servidor:

• Unmarshall dos argumentos; • Chamada do procedimento correto; • Marshalling dos argumentos; • Envio da resposta.

31 SD Cap. 5-6 31 SD Cap. 5-6

Principais componentes do atraso de um RPC: • Marshalling: significa copiar e converter dados;

• Cresce à medida que a quantidade de dados aumenta. • Cópia de dados:

• Cópia de memória para memória fica em torno de 10 MB/seg. nos processadores mais rápidos;

• Mesma taxa de transferência de uma rede 100 Mbits/seg; • Uma mensagem pode ser copiada diversas vezes num RPC:

• Entre usuário e kernel; • Entre cliente e servidor; • Nos buffers do kernel; • Entre as camadas dos protocolos; • Entre as interfaces de rede e os buffers do kernel.

Obs.: no sentido interface-memória (na chegada), a transferência é feita por DMA. • Inicialização de pacotes (headers, checksums, etc.): custo

proporcional à quantidade de dados; • Escalonamento de threads e troca de contexto:

• RPC invoca sistema de comunicação do kernel; • Aplicação usa threads para fazer um RPC; • Se há um processo gerente de rede, um Send implica em

troca de contexto.

6.6 Memória virtual Objetivo: executar grandes problemas e combinações de programas cuja soma de código e dados é maior que a memória principal:

Parte da memória é usada como cache do sistema de armazenamento.

Por manter apenas as seções de código e dados atualmente em uso pelos processos, é possível: Executar programas maiores que a memória principal; Aumentar o nível de multiprogramação ao aumentar o número

de processos na memória principal; Liberar os programadores das limitações da memória física.

Idéia generalizada para abranger o acesso a arquivos mapeados em áreas de memória: Um processo lê ou grave dados no arquivo lendo ou gravando

num array em memória; Um arquivo aberto para uma linguagem de alto nível aparece

como um array; O kernel é responsável por trazer mais dados à medida que os

dados do array são lidos; O kernel transfere os dados para disco à medida que eles são

alterados Ex.: MULTICS, SunOS. Demand paging: uma página só é carregada por demanda (isto é, quando alguém precisa, ela é carregada para a memória principal). Gerenciadores externos Em um SD, o computador que recebe um page fault não precisa ser o mesmo que gerencia os dados: Ex.: o 1o pode ser diskless; O gerente é um servidor de arquivos remoto;

32 SD Cap. 5-6 32 SD Cap. 5-6

O uso de gerenciadores externos permite implementar esquemas

customizados de paginação; Uma abordagem para implementar memória compartilhada

distribuída; O kernel continua responsável por:

tratar page faults; gerência da memória principal; política de alocação; política de substituição.

Função do gerenciador externo: Receber e tratar dados de páginas purgadas pelo kernel; Fornecer páginas ao kernel conforme ele peça; Impor restrições aos diversos kernels que acessam uma área

(todos podem tentar manter caches de áreas modificáveis).

Espaço de endereça- mento

Kernel Kernelrede

Page fault msgs

Gerente externo