220 likes | 327 Views
Concorrência e thread. Petrônio Júnior(pglj) Márcio Neves(mmn2). Concorrência. Concorrência ocorre devido à disputa de recursos compartilhados. Se dois clientes, por exemplo, tentam alterar um mesmo objeto, uma inconsistência pode ser gerada. Sincronização – o que é?.
E N D
Concorrência e thread Petrônio Júnior(pglj) Márcio Neves(mmn2)
Concorrência • Concorrência ocorre devido à disputa de recursos compartilhados. • Se dois clientes, por exemplo, tentam alterar um mesmo objeto, uma inconsistência pode ser gerada.
Sincronização – o que é? • Em uma aplicação distribuída, vários computadores com diferentes capacidades de processamento e diferentes conexões de rede trabalham em conjunto. Devido a essas diferenças, eventos que deveriam ocorrer em determinada ordem são observados fora da ordem esperada. • Por isso é necessário algum meio de sincronização.
Alguns problemas com Concorrência Não-determinismo: • x = 1 || x = 2 • Podemos não saber ao certo qual o valor correto. Dependência de Velocidade: • [[ f(); x = 1 ]] || [[ g(); x = 2 ]] • O valor final de x depende de qual das funções, f() e g(), terminar primeiro
Alguns problemas com Concorrência Starvation: • Processo de baixa prioridade precisa de um recurso que nunca é fornecido a ele Deadlock: • Dois processos bloqueiam a sua execução pois um precisa de um recurso bloqueado pelo outro processo
Como Resolver? • Linguagens de programação geralmente oferecem primitivas para evitar a ocorrência desses problemas • Principais recursos para evitar a concorrência: • Eventos • Semáforos • Monitores • Mensagens
Eventos – O que são? • Modelam uma ocorrência do sistema • Primitivas: • wait(x): Espera (bloqueia o processo até) que ocorra um certo evento “x” • signal(x): Gera uma ocorrência do evento “x”, reativando todos os processos que foram bloqueados por um wait anterior.
Semáforos – O que são? • Variáveis que indicam se um recurso está disponível para uso ou não. • Operações Principais: • initialize(x,n): Inicializa o semáforo “x” e garante que no máximo “n” processos utilizarão esse recurso. Se algum outro tentar utilizá-lo, não será permitido.
Semáforos – O que são? • wait(x): Obtém um recurso do semáforo “x”. Se nenhum estiver disponível, o processo é bloqueado • signal(x): Libera um recurso do semáforo “x”. Se algum processo estiver bloqueado, ou seja, se tentou obter certo recurso e este não estava disponível causando o seu bloqueio, então esse processo será liberado e autorizado a usar o recurso.
Monitores – O que são? • Apenas um processo pode executar funções em um determinado momento • Em Java temos o modificador synchronized. • Esse modificador faz com que um objeto que está sendo acessado só possa ser acessado novamente quando a tarefa que está sendo realizada sobre ele seja concluída.
Mensagens – O que são? • Define mensagens que são enviadas entre processos. Essas mensagens podem ser síncronas ou assíncronas. • Primitivas: • Send(x,p): Envia a mensagem “x” para o processo p. • Receive(x): Espera até que uma mensagem “x” esteja disponível • Test(): Verifica se existe uma mensagem disponível
Thread • Um thread é um fluxo único de controle sequencial dentro de um programa • É uma forma de um processo dividir a si mesmo em tarefas que passam a dividir o tempo que ele tem pra ser executado, executando, dessa forma, “simultaneamente”.
Thread • Um thread não é um programa, mas executa dentro de um programa.
Thread • O overhead causado pelo thread é menor que o do escalonamento de processos embora a mesma memória seja compartilhada. • Além da memória, threads compartilham o estado da informação de processos. • Quanto mais threads mais complicada a sincronia com a principal (se for requerida)
Thread • Em java, temos duas alternativas para implementar o recurso de multi-thread:a) Estendendo da Classe Thread public class Execucao { public static void main(String[] args) { Proc p = new Proc(); p.start(); while (true) { System.out.println("thread main executando");} }} class Proc extends Thread { public void run() { while (true) { System.out.println("thread executando");} }}
Thread b) Implementando a Interface Runnable public class Execucao { public static void main(String[] args) { Proc p = new Proc(); Thread t = new Thread(p); t.start(); while (true) { System.out.println("thread main executando"); } } } class Proc implements Runnable { public void run() { while (true) {System.out.println("thread executando");} } }
Thread • O método main é uma thread e instancia um objeto p que também é instância de uma classe que estende de Thread. O método start() chamado, informa ao escalonador de thread que coloque na fila de execução a Thread p. • A thread p não vai executar imediatamente quando o método start foi chamado, somente sinaliza o escalonador
Socket • Sockets são interfaces de programação que estão entre a camada de transportes e a aplicação. São como portas que possibilitam a comunicação entre componentes distribuídos, de aplicações, em uma rede de computadores. É um tipo de programação necessária para a criação de sistemas distribuídos como o RMI e o CORBA.
Socket • Processos em hosts distintos comunicam-se por meio de envio de mensagens enviadas e recebidas através de seu socket. Em uma aplicação distribuída pode-se enviar um fluxo de informações para outra através dos sockets. • Ao utilizar sockets, o programador deve utilizar o tipo adequado ao protocolo de transporte utilizado: protocolo orientado à conexão (confiável) ou protocolo não orientado à conexão (não confiável), também conhecido como datagrama.
Socket • A linguagem Java oferece packages para a programação com Sockets e para a programação através de invocação remota de métodos ou RMI (Remote Method Invocation).Entretanto, também temos implementações de RPC e de Sockets para outras linguagem, como o CORBA (implementação do RPC para varias linguagens). • Exemplo de uma aplicação Java que utiliza a programação em Socket para estabelecer uma conexão e enviar uma mensagem pela rede. Utiliza a arquitetura Cliente-Servidor.
Socket – Classe Servidor • import java.io.*; • import java.net.*; • publicclass Servidor { • publicstaticvoid main(String[] args) throws IOException { • final String mensagem = "Oi! Tudo bem?"; • ServerSocket socketServidor = new ServerSocket(8080); // criacao do socket no servidor • System.out.println ("Servidor ativado. Aguardando na porta 8080...\n"); • Socket socketCliente = socketServidor.accept( ); // servidor aguarda cliente • OutputStream fluxoSaiSocket = socketCliente.getOutputStream( ); // define fluxo de saida • PrintWriter saida = new PrintWriter(fluxoSaiSocket, true); • InputStream fluxoEntSocket = socketCliente.getInputStream( ); // define fluxo de entrada • BufferedReader entrada = new BufferedReader(new InputStreamReader(fluxoEntSocket)); • String msgRecebida = entrada.readLine( ); // recebe mensagem do cliente • System.out.println ("Mensagem Recebida: <" + msgRecebida + ">"); • saida.println(mensagem); // envia mensagem para o cliente • System.out.println ("Mensagem Enviada: <" + mensagem + ">\n"); • socketCliente.close( ); • socketServidor.close( ); • saida.close( ); • entrada.close( ); • } • }
Socket – Classe Cliente • import java.io.*; • import java.net.*; • publicclass cliente { • publicstaticvoid main (String[] args) throws IOException { • final String mensagem = "Oi!"; • try { • Socket socketCliente = new Socket("localhost", 8080); // criacao do socket no cliente • OutputStream fluxoSaiSocket = socketCliente.getOutputStream( ); // define fluxo de saida • PrintWriter saida = new PrintWriter(fluxoSaiSocket, true); • InputStream fluxoEntSocket = socketCliente.getInputStream( ); // define fluxo de entrada • BufferedReader entrada = new BufferedReader(new InputStreamReader(fluxoEntSocket)); • saida.println(mensagem); // envia mensagem para o servidor • System.out.println("Mensagem Enviada: <" + mensagem + ">"); • String msgRecebida = entrada.readLine( ); // recebe mensagem do servidor • System.out.println ("Mensagem Recebida: <" + msgRecebida + ">\n"); • socketCliente.close( ); • saida.close( ); • entrada.close( ); • } • catch(UnknownHostException e) { • System.err.println("Host nao encontrado!"); • System.exit(1); • } • catch(java.io.IOException e) { • System.err.println("Conexao nao pode ser estabelecida!"); • System.exit(1); • } • } • }