Please enable JavaScript.
Coggle requires JavaScript to display documents.
Capítulo 8 Comunicação entre tarefas - Coggle Diagram
Capítulo 8
Comunicação entre tarefas
8.1 Objetivos
Nem sempre um programa sequencial é a melhor solução para um determinado problema. Existem várias razões para justificar a construção de sistemas baseados em tarefas cooperantes, entre as quais podem ser citadas:
Uso de computadores multiprocessador:
um programa sequencial executa um único fluxo de instruções por vez. Para aumentar a velocidade de execução de uma aplicação, esta deve ser “quebrada” em várias tarefas cooperantes
Modularidade:
um sistema muito grande e complexo pode ser melhor organizado dividindo suas atribuições em módulos sob a responsabilidade de tarefas interdependentes. Cada módulo tem suas próprias responsabilidades e coopera com os demais módulos quando necessário.
Atender vários usuários simultâneos:
um servidor completamente sequencial atenderia um único cliente por vez, gerando atrasos intoleráveis. Por isso, servidores de rede são implementados com vários processos ou threads.
Construção de aplicações interativas:
navegadores Web, editores de texto e jogos são exemplos de aplicações com alta interatividade. Construir esse tipo de aplicação de forma totalmente sequencial seria simplesmente inviável.
8.2 Escopo da comunicação
Tarefas cooperantes precisam trocar informações entre si
Implementação:
Se as tarefas estão no mesmo processo, elas compartilham a mesma área de memória e a comunicação pode então ser implementada facilmente, usando variáveis globais comuns.
Se as tarefas estão em processos distintos, não existem variáveis compartilhadas. Então a comunicação tem de ser feita por intermédio do SO, usando chamadas de sistema.
8.3 Aspectos da comunicação
8.3.1 Comunicação direta ou indireta
Direta:
o emissor identifica claramente o receptor e vice-versa, utilizando as primitivas
enviar (dados, destino)
e
receber (dados, origem)
. (pouco utilizado)
Indireta:
emissor e receptor não precisam se conhecer, pois não interagem diretamente entre si. Eles se relacionam através de um canal de comunicação, que é criado pelo sistema operacional e utilizam as primitivas
enviar (dados, canal)
e
receber (dados, canal).
8.3.2 Sincronismo
A comunicação
entre tarefas pode ser:
Síncrona (ou bloqueante):
as operações de envio e recepção de dados suspendem as tarefas envolvidas até a conclusão da comunicação: o emissor será bloqueado até que a informação seja recebida pelo receptor, e vice-versa.
Assíncrona (ou não-bloqueante):
as primitivas não são bloqueantes. Caso a comunicação não seja possível naquele momento, é retornada com uma indicação de erro. Caso o emissor e o receptor operem ambos de forma assíncrona, é necessário criar um canal ou buffer para armazenar os dados da comunicação entre eles.
Semissíncrona (ou semibloqueante):
têm um comportamento síncrono (bloqueante) durante um
prazo
predefinido. Caso esse prazo se esgote sem que a comunicação tenha ocorrido, a primitiva se encerra com uma indicação de erro.
8.3.3 Formato de envio
Sequência de Mensagens:
cada mensagem consiste de um pacote de dados que pode ser tipado ou não. Esse pacote é recebido ou descartado pelo receptor em sua íntegra; não existe a possibilidade de receber “meia mensagem”. (protocolo UDP)
Fluxo Sequencial:
canal de comunicação é visto como um arquivo: o emissor “escreve” dados nesse canal, que serão “lidos” pelo receptor respeitando a ordem de envio dos dados.
8.3.4 Capacidade dos canais
Capacidade infinita (n = ∞):
o emissor sempre pode enviar dados, que serão armazenados no buffer do canal enquanto o receptor não os consumir (não existe na prática)
Capacidade finita (0 < n < ∞):
uma quantidade finita (n) de dados pode ser enviada pelo emissor sem que o receptor os consuma. Todavia, ao tentar enviar dados em um canal já saturado, o emissor poderá ficar bloqueado até surgir espaço no buffer. (mais utilizado)
Capacidade nula (n = 0):
o canal não pode armazenar dados, a comunicação é feita por transferência direta dos dados do emissor para o receptor,
8.3.5 Confiabilidade dos canais
Canal Confiável:
transporta todos os dados enviados através dele para seus receptores, respeitando seus valores e a ordem em que foram enviados
Canal FIFO ou Ordenado:
canal em que a ordem dos dados é garantida
Canal Não-Confiável:
há várias possibilidades de erros envolvendo o canal de comunicação:
Perda de dados:
nem todos os dados enviados através do canal chegam ao seu destino
Perda de integridade:
os dados enviados pelo canal chegam ao seu destino, mas podem ocorrer modificações em seus valores devido a interferências externas
Perda da ordem:
todos os dados enviados chegam íntegros ao seu destino, mas o canal não garante que eles serão entregues na ordem em que foram enviados
8.3.6 Número de participantes
Existem situações em que uma tarefa necessita comunicar com várias outras, dessa forma, os mecanismos de comunicação também podem ser classificados de acordo com o número de tarefas participantes:
1:1:
quando exatamente um emissor e um receptor interagem através do canal de comunicação. (situação mais frequente)
M:N:
quando um ou mais emissores enviam mensagens para um ou mais receptores.
Apenas um receptor:
Cada mensagem é recebida por apenas um receptor (em geral aquele que pedir primeiro) e a comunicação continua sendo ponto-aponto
Vários receptores:
Cada mensagem é recebida por vários receptores (cada um recebe uma cópia da mensagem). É conhecida como barramento de mensagens, canal de eventos ou ainda canal publish-subscribe