Prévia do material em texto
Sistemas Distribuídos e Taxonomia de Flynn
Os sistemas distribuídos são aqueles em que componentes de computadores interligados
em rede se comunicam e coordenam suas ações por meio da troca de mensagens. São
amplamente utilizados em aplicações como buscas na web, home banking, redes sociais,
streaming, IoT, monitoramento de saúde, entre outros.
Principais características dos sistemas distribuídos:
• Concorrência: múltiplos processos podem ser executados simultaneamente.
• Ausência de um relógio global: não há uma noção única de tempo entre os
sistemas.
• Falhas independentes: cada componente pode falhar sem comprometer o sistema
inteiro.
A principal motivação para sistemas distribuídos é o compartilhamento de recursos, sejam
eles hardware (como bancos de dados e servidores) ou informações.
Taxonomia de Flynn
A computação paralela divide os trabalhos em partes que podem ser executadas
simultaneamente em diferentes processadores. A classificação proposta por Flynn (1966)
categoriza as arquiteturas computacionais em quatro tipos:
1. SISD (Single-Instruction, Single-Data): Computadores sequenciais que processam
uma única instrução em um único fluxo de dados (ex.: PC tradicional).
2. SIMD (Single-Instruction, Multiple-Data): Uma mesma instrução é aplicada
simultaneamente a diferentes dados (ex.: GPUs).
3. MISD (Multiple-Instruction, Single-Data): Processadores aplicam diferentes
instruções a um mesmo fluxo de dados (modelo teórico pouco utilizado).
4. MIMD (Multiple-Instruction, Multiple-Data): Diferentes instruções são aplicadas a
diferentes dados, sendo amplamente utilizado em sistemas distribuídos.
Os sistemas MIMD podem ter memória compartilhada (mais fácil de programar, porém
menos escalável) ou memória distribuída (mais tolerante a falhas e escalável).
Lei de Amdahl e Speedup
A Lei de Amdahl afirma que a melhoria no desempenho ao adicionar mais processadores é
limitada pela fração do programa que não pode ser paralelizada. Isso significa que, mesmo
com um grande número de processadores, haverá um ponto onde o aumento de velocidade
se torna insignificante.
Desafios e Benefícios dos Sistemas Distribuídos
Benefícios:
• Maior poder computacional.
• Redução de custos ao utilizar múltiplos sistemas menores.
• Escalabilidade e flexibilidade.
Desafios:
• Comunicação entre nós pode gerar latência.
• Coordenação e sincronização são complexas.
• Segurança e tolerância a falhas são críticas.
Resumo para Prova: Memória
Compartilhada e Memória Distribuída
1. Memória Compartilhada
• Utiliza um único espaço de memória acessado simultaneamente por vários programas
ou threads.
• Permite comunicação rápida entre processos e economia de recursos.
• Pode ser implementada via Interprocess Communication (IPC), onde um processo
cria uma área na RAM acessível por outros processos.
• Escalabilidade limitada, pois os processos devem rodar na mesma máquina.
• Problemas de coerência de cache podem ocorrer se os processos estiverem em
CPUs diferentes.
1.1 Paralelização com OpenMP
• OpenMP é uma biblioteca usada para paralelizar programas em C/C++.
• O código paralelizado é definido usando #pragma omp parallel.
Exemplo:
#include
#include
int main() {
#pragma omp parallel
{
printf("Ola Mundo... da thread = %d\n", omp_get_thread_num());
}
return 0;
}
Para definir o número de threads: export OMP_NUM_THREADS=5.
Compilando e executando no Linux:
gcc -o hello -fopenmp hello.c
./hello
•
• A execução pode ter diferentes ordens de saída devido à execução paralela.
2. Memória Distribuída
• Cada processador tem sua própria memória privada.
• Para acessar dados de outro processador, é necessária comunicação explícita.
• A interconexão pode ser ponto a ponto ou via rede de comutação.
• Utiliza comunicação assíncrona para reduzir latência.
• A distribuição de dados pode ser estática ou dinâmica.
• Mais escalável que a memória compartilhada, pois permite adicionar novos nós à
rede.
2.1 Paralelização com MPI
• MPI (Message Passing Interface) é uma biblioteca para memória distribuída.
• Cada processador executa cópias separadas do programa.
Exemplo de código MPI:
#include "mpi.h"
#include
int main(int argc, char *argv[]) {
int numtasks, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
printf("Number of tasks= %d My rank= %d\n", numtasks, rank);
MPI_Finalize();
return 0;
3. Comparando Memória Compartilhada e Memória
Distribuída
Característica Memória Compartilhada Memória Distribuída
Espaço de
Memória
Compartilhado Separado para cada
processador
Velocidade de
Acesso
Alta (menos latência) Menor (devido à
comunicação)
Escalabilidade Limitada Alta (adição de novos nós)
Concorrência Condições de corrida podem
ocorrer
Não há condições de corrida
Biblioteca utilizada OpenMP
Paralelismo de Dados vs. Paralelismo de Tarefas
Paralelismo de Dados
O paralelismo de dados ocorre quando grandes conjuntos de dados são divididos e
processados simultaneamente por múltiplos processadores. Esse modelo se baseia na
execução da mesma operação em diferentes partes dos dados ao mesmo tempo.
Características:
• Os dados são distribuídos entre diferentes processadores.
• É aplicável a estruturas regulares como matrizes e arrays.
• Acelera o processamento de grandes volumes de dados.
• Executado comumente em sistemas de computação massivamente paralelos (SIMD
– Single Instruction Multiple Data).
Exemplo:
Na multiplicação de matrizes, cada processador pode calcular uma parte da matriz resultante
simultaneamente. Isso reduz significativamente o tempo de execução em comparação com
um processamento sequencial.
Importância da Localidade de Dados:
• O desempenho depende do acesso eficiente à memória.
• A arquitetura da cache influencia a velocidade da computação.
• Em sistemas multiprocessadores, otimizar a distribuição dos dados melhora o
desempenho global.
Paralelismo de Tarefas
O paralelismo de tarefas ocorre quando diferentes tarefas ou funções são executadas
simultaneamente por múltiplos processadores. Aqui, cada processador pode executar um
conjunto diferente de instruções sobre os mesmos ou diferentes conjuntos de dados.
Características:
• As tarefas são distribuídas entre diferentes processadores.
• Threads ou processos distintos podem executar códigos diferentes.
• Ocorre frequentemente em aplicações que exigem múltiplas operações simultâneas,
como servidores e bancos de dados.
• Utilizado em sistemas multiprocessadores com modelos de memória compartilhada e
distribuída.
Exemplo:
Se um sistema precisa processar imagens e enviar relatórios simultaneamente, um
processador pode estar analisando pixels de uma imagem enquanto outro gera um relatório
com os resultados.
Comparação entre Paralelismo de Dados e Paralelismo de Tarefas
Característica Paralelismo de Dados Paralelismo de Tarefas
Foco Processamento paralelo dos dados Execução paralela de múltiplas
tarefas
Estratégia Divisão de dados entre
processadores
Distribuição de diferentes
funções entre processadores
Modelo SIMD (Single Instruction Multiple
Data)
MIMD (Multiple Instruction
Multiple Data)
Exemplo Multiplicação de matrizes
paralelizada
Execução simultânea de
operações distintas
Uso Típico Processamento gráfico, análise de
grandes volumes de dados
Sistemas distribuídos,
servidores, bancos de dados
Conclusão
O paralelismo de dados é eficiente para tarefas repetitivas sobre grandes conjuntos de dados,
enquanto o paralelismode tarefas é ideal para sistemas que exigem múltiplas funções sendo
executadas simultaneamente. Ambos são essenciais na otimização de desempenho em
sistemas computacionais modernos, incluindo inteligência artificial, computação científica e
servidores de alto desempenho.
Arquiteturas e Conceitos de Sistemas Distribuídos
1. Arquitetura Mestre-Escravo
• Definição: Em sistemas mestre-escravo, um mestre centraliza o controle e distribui
tarefas para componentes escravos, que as executam. O mestre também pode
gerenciar os escravos, incluindo sua inicialização e controle de falhas.
Vantagens:
o Alta tolerância a falhas. Se um escravo falhar, a tarefa é atribuída a outro.
o Facilidade em substituir escravos falhos, minimizando impactos no
desempenho.
Desvantagens:
o Necessidade de tarefas independentes para facilitar a distribuição entre os
escravos.
o O mestre pode ficar sobrecarregado em sistemas com muitos escravos, o que
pode gerar problemas de performance e saturação de comunicação.
Variantes:
o Mestre-Escravo Simples: Um único mestre supervisiona todos os escravos.
o Mestre-Escravo Multinível: Introdução de múltiplos níveis de mestres para
distribuir a supervisão e evitar sobrecarga.
o Master Sobressalente: Vários mestres secundários, garantindo alta
disponibilidade. Se o mestre principal falhar, outro o substitui rapidamente.
o Mestre com Redundância Passiva: Similar ao modelo anterior, mas o mestre
secundário está constantemente atualizado para minimizar a latência de
substituição.
Usos comuns: Arquitetura mestre-escravo é aplicada em sistemas de tempo real, redes de
dispositivos embarcados, e replicação de banco de dados, onde o banco mestre é a fonte de
dados e os escravos são sincronizados com ele.
2. Polling
• Definição: O polling é um mecanismo onde um dispositivo de controle interroga
periodicamente outros dispositivos ou recursos para verificar seu estado (prontidão ou
disponibilidade).
Mecanismo:
o O controlador consulta cada dispositivo ou recurso até que esteja pronto para
executar a tarefa solicitada.
Vantagens:
o Menos desperdício de CPU do que a espera ocupada.
Desvantagens:
o Em sistemas com muitos dispositivos, o tempo para percorrer todos os
dispositivos pode ser longo, gerando um overhead considerável.
Tipos de Polling:
o Votação Nominal (Roll Call Polling): O controlador consulta cada recurso de
forma sequencial.
o Hub Polling (Token Polling): Um recurso consulta o próximo da sequência
de maneira cíclica, reiniciando o ciclo quando chega ao primeiro.
Aplicações: Usado em sistemas multitarefa para controle de acesso a dispositivos de E/S,
como impressoras ou redes de comunicação.
3. Redes Peer-to-Peer (P2P)
• Definição: Em redes P2P, todos os participantes (nós) atuam tanto como clientes
quanto servidores, compartilhando recursos como armazenamento, processamento e
largura de banda. Não há um servidor central, e todos os dispositivos podem fornecer
ou consumir recursos.
Exemplo: Protocolos como BitTorrent e sistemas de criptomoedas utilizam arquitetura P2P
para distribuir conteúdos de forma descentralizada, aproveitando o poder de processamento
e o armazenamento de cada nó.
Vantagens:
o Não há dependência de um servidor central, o que torna a rede mais resiliente
a falhas.
o Grande escalabilidade, pois os recursos aumentam à medida que novos nós
se juntam à rede.
Desvantagens:
o Dependência do comportamento dos usuários para manter a rede eficiente, o
que pode ser problemático em redes muito grandes.
4. Clusters de Computadores
• Definição: Um cluster é um conjunto de computadores interconectados que
funcionam juntos para oferecer melhor desempenho e/ou maior disponibilidade. Eles
podem ser classificados de acordo com o objetivo:
Tipos de Cluster:
o Cluster de Alto Desempenho: Focado em processar grandes cargas de
trabalho com custo reduzido, utilizando hardware comum.
o Cluster de Alta Disponibilidade: Visa garantir que o sistema esteja sempre
disponível, mesmo que um nó falhe.
o Cluster de Balanceamento de Carga: Distribui as tarefas entre os nós de
forma equilibrada para melhorar a performance e evitar sobrecarga.
Benefícios:
o Aumento de performance: A carga de trabalho é dividida entre vários nós.
o Alta disponibilidade: A redundância de nós permite a continuidade das
operações mesmo em caso de falha de algum nó.
Desafios:
o Comunicação frequente entre os nós pode afetar o desempenho.
o Gestão de falhas e balanceamento de carga precisam ser bem planejados
para garantir a eficiência do sistema.
Sistemas de Memória Compartilhada e Concorrência
o 1. Variáveis Compartilhadas: Em programas de memória
compartilhada, as variáveis podem ser:
• Compartilhadas: Acessíveis por múltiplos threads.
• Privadas: Cada thread possui sua própria cópia.
o Em sistemas com threads, as variáveis compartilhadas podem ser lidas
e modificadas por qualquer thread, enquanto as privadas só são
acessadas por seu thread correspondente. A comunicação entre
threads usando variáveis compartilhadas é implícita.
o 2. Modelos de Threads:
• Thread Dinâmico: Um thread mestre espera por solicitações e cria threads de
trabalho para processá-las. Após a conclusão, o thread de trabalho se junta ao
mestre.
o Vantagem: Uso eficiente de recursos, pois os threads existem somente
enquanto estão em execução.
• Thread Estático: Todos os threads são criados no início, e executam suas
tarefas até a conclusão.
o Vantagem: Pode ser mais eficiente se os recursos estiverem
disponíveis, mas pode desperdiçar recursos quando os threads ficam
ociosos.
o 3. Cálculo Não Determinístico: Em sistemas MIMD (Multiple
Instruction, Multiple Data), onde os processadores trabalham de forma
assíncrona, o cálculo pode ser não determinístico, ou seja, a mesma
entrada pode resultar em saídas diferentes em execuções distintas. Isso
ocorre porque a ordem de execução das instruções dos threads pode
variar entre as execuções, gerando resultados diferentes.
o Exemplo: Dois threads tentando atualizar uma variável compartilhada
podem resultar em diferentes sequências de saída, dependendo de qual
thread executa primeiro.
o 4. Condição de Corrida: A condição de corrida acontece quando
múltiplos threads tentam acessar simultaneamente uma variável
compartilhada sem controle adequado. Isso pode levar a resultados
incorretos, pois o estado da variável depende de qual thread “vence a
corrida”.
o Exemplo:
o Quando dois threads tentam somar seus valores em uma variável
compartilhada, como x += val;, sem sincronização, o resultado final pode
ser incorreto devido à execução simultânea das operações.
o 5. Seções Críticas e Mutex: Uma seção crítica é um bloco de código
que deve ser executado por apenas um thread de cada vez. Para
controlar o acesso a essas seções, usamos o mutex (mecanismo de
exclusão mútua):
• Um thread deve "adquirir" o mutex antes de acessar a seção crítica e "liberá-
lo" após concluir.
• Exclusão Mútua: Garante que apenas um thread execute a seção crítica de
cada vez.
o 6. Alternativas ao Mutex: Espera Ocupada Em vez de usar mutex,
podemos usar uma técnica chamada espera ocupada, onde um thread
entra em um loop verificando repetidamente uma condição para acessar
a seção crítica. Porém, isso pode desperdiçar recursos, pois o thread
fica ocupado aguardando.
o Exemplo de Espera Ocupada:
o while (ok != 1); // Espera ocupada
ok = 0; // Bloqueia outro thread
x += my_val; // Seção crítica
ok = 1; // Libera
o 7. Memória Compartilhada entre Processos: Além de usar memória
compartilhada dentro de um processo, é possível usar entre processos
distintos. Para isso, são feitas operações de criação, anexação,
manipulação e desanexação de segmentos de memória compartilhada.
o Passos paraUsar Memória Compartilhada:
• Criar o segmento de memória compartilhada.
• Anexar o segmento ao processo.
• Realizar leituras e gravações na memória.
• Desanexar o segmento após o uso.
o Essas operações permitem a comunicação entre processos e são
fundamentais para sistemas distribuídos.
o Este resumo foca nos conceitos chave de memória compartilhada,
concorrência e sincronização, além de explicar como evitar
problemas comuns como condições de corrida e o uso de mutex e
espera ocupada. Esses tópicos são cruciais para entender como os
threads e processos interagem e como garantir um funcionamento
correto e eficiente dos sistemas concorrentes.
Identificação de Problemas e Soluções no Uso de Variáveis
Compartilhadas
1. Conceitos Básicos
• Variáveis Compartilhadas: Acessíveis por múltiplos threads dentro de um
processo.
• Variáveis Privadas: Restringidas a um único thread.
• A comunicação entre threads em memória compartilhada é implícita (diferente
de soquetes e pipes).
2. Modelos de Gerenciamento de Threads
• Thread Dinâmico:
o Um thread mestre cria threads de trabalho conforme necessário.
o Vantagem: Uso eficiente de recursos.
• Thread Estático:
o Todos os threads são iniciados no começo e executam até a finalização
do programa.
o Vantagem: Pode ser mais eficiente quando os recursos estão
disponíveis.
3. Cálculo Não Determinístico e Condição de Corrida
• O cálculo é não determinístico quando a execução paralela dos threads pode
produzir diferentes saídas.
• Condição de Corrida: Ocorre quando múltiplos threads acessam e modificam
uma variável compartilhada simultaneamente, causando resultados incorretos.
• Exemplo:
val = Compute_val(my_rank);
x += val;
o Se dois threads executarem essa instrução ao mesmo tempo sem
controle, x pode ter um valor inesperado.
4. Solução: Exclusão Mútua (Seções Críticas e Mutex)
• Seção Crítica: Parte do código que deve ser executada por um único thread
por vez.
• Mutex (Mutual Exclusion Lock): Bloqueia o acesso de outros threads até a
finalização da seção crítica.
Lock(&mutex);
x += val;
Unlock(&mutex);
o Vantagem: Garante consistência dos dados.
o Desvantagem: Pode reduzir o desempenho se for mal utilizado.
5. Alternativa: Espera Ocupada
• Um thread entra em um loop de espera, verificando constantemente uma
condição antes de acessar a seção crítica.
while (ok != 1);
ok = 0;
x += val;
ok = 1;
o Problema: O desperdício de recursos, pois o thread fica ocupado
mesmo sem executar tarefas úteis.
6. Uso de Memória Compartilhada entre Processos
• Diferente do uso dentro de um único processo (com threads), a memória
compartilhada pode ser usada entre processos distintos.
• Passos no Linux:
o Criar o segmento de memória (shmget()).
o Anexar o segmento (shmat()).
o Escrever e ler os dados.
o Desanexar o segmento (shmdt()).
o Remover a memória compartilhada (shmctl()).
Resumo Final
• O uso de variáveis compartilhadas exige cuidado para evitar condições de
corrida.
• Mutex é a solução mais comum para garantir exclusão mútua.
• Memória compartilhada entre processos requer chamadas de sistema
específicas.
• Técnicas como espera ocupada podem ser usadas, mas são ineficientes.
• 1. Condições de Corrida
• Definição: Quando a saída de um programa depende da ordem/timing de
eventos concorrentes.
• Bug crítico: Pode causar resultados inesperados e difíceis de depurar
(heisenbug).
• Exemplo: Dois threads incrementando uma variável ao mesmo tempo sem
sincronização, resultando em valores errados.
• 2. Sincronização de Processos
• Objetivo: Coordenar processos para evitar conflitos em recursos
compartilhados.
• Seção Crítica: Parte do código onde ocorre o acesso a um recurso
compartilhado.
• Regras para solução eficiente:
o Dois processos não podem estar na seção crítica ao mesmo tempo.
o Deve funcionar independentemente da velocidade/número de CPUs.
o Processos fora da seção crítica não podem bloquear outros.
o Nenhum processo pode esperar eternamente.
• 3. Exclusão Mútua
• Definição: Garante que apenas um processo acesse um recurso compartilhado
por vez.
• Mecanismos:
o Locks/Mutexes: Bloqueiam o recurso até que um processo termine.
o Semáforos: Controlam múltiplos acessos concorrentes.
o Operações Atômicas: Executadas sem interferência de outros
processos.
•
• 4. Problemas Clássicos de Sincronização
• Produtor-Consumidor
• Cenário: Um produtor gera dados e coloca em um buffer, enquanto o
consumidor lê e processa.
• Desafio: Evitar sobrecarga (buffer cheio) ou subutilização (buffer vazio).
• Leitores-Escritores
• Cenário: Um arquivo é acessado por leitores e escritores simultaneamente.
• Regra: Vários leitores podem acessar ao mesmo tempo, mas escritores
precisam de exclusividade.
• Jantar dos Filósofos
• Cenário: Cinco filósofos compartilham cinco hashis para comer.
• Problema: Se todos pegarem um hashi e esperarem o segundo, ninguém come
(deadlock).
• 5. Problemas Relacionados à Concorrência
• Deadlock
• O que é: Processos ficam presos esperando recursos uns dos outros.
• Exemplo: Um processo bloqueia um arquivo enquanto outro precisa dele para
continuar.
• Starvation (Fome)
• O que é: Um processo nunca consegue acessar a seção crítica porque outros
monopolizam o recurso.
• Exemplo: Um processo de baixa prioridade nunca recebe tempo de CPU.
• Inversão de Prioridade
• O que é: Um processo de alta prioridade é atrasado por um de menor
prioridade.
• Exemplo: Um processo importante esperando um recurso preso por um
processo menos prioritário.
• Espera Ocupada
• O que é: Um processo verifica repetidamente se um recurso está disponível,
desperdiçando CPU.
•
• 6. Soluções para Condições de Corrida
• Operações Atômicas
• Executadas completamente sem interferência externa.
• Locks e Mutexes
• Impedem que múltiplos processos acessem um recurso ao mesmo tempo.
• Semáforos
• Controlam quantos processos podem acessar um recurso simultaneamente.
1. Ignorando o Deadlock
• Supõe-se que deadlocks são raros e que a perda de dados é aceitável.
• Pode ser aplicado se for comprovado que deadlocks nunca ocorrem.
2. Detecção de Deadlocks
• O sistema monitora recursos e processos para identificar deadlocks.
• Quando detectado, pode ser corrigido de duas formas:
o Encerramento de processos:
▪ Abortar um ou mais processos envolvidos no impasse.
▪ Pode causar perda de processamento e requer análise criteriosa.
o Preempção de recursos:
▪ Recurso bloqueado é removido de um processo e realocado.
▪ Pode causar inconsistências e alto custo de reversão.
3. Prevenção de Deadlocks
• Evita que pelo menos uma das quatro condições de Coffman ocorra:
o Exclusão mútua → Nenhum processo pode ter acesso exclusivo a um
recurso.
o Retenção e espera → Um processo deve solicitar todos os recursos
antes de começar.
o Ausência de preempção → Recursos podem ser removidos de
processos se necessário.
o Espera circular → Os processos devem requisitar recursos em uma
ordem específica.
4. Algoritmos para Evitar Deadlocks
• Algoritmos sem bloqueio: Garantem que processos não fiquem presos.
• Tokens de serialização (tudo ou nada): O processo só recebe recursos se
todos estiverem disponíveis.
• Controle de simultaneidade otimista: Processos verificam se um deadlock
ocorreu antes de continuar.
5. Deadlocks em Sistemas Distribuídos
• Ocorrem quando processos remotos competem por recursos.
• Tipos:
o Deadlock fantasma → Ocorre devido a atrasos na comunicação, mas
não é real.
o Deadlock de recurso → Processos aguardam recursos uns dos outros
indefinidamente.
o Deadlock de comunicação → Processos esperam comunicação de
outros que também estão aguardando.
o 🧠 Dica Final:
• Semáforo → Controle manual.Pode errar fácil.
• Mutex → Controle mais simples para proteger pedaços do código.
• Monitor → Controle automático. A linguagem ou sistema cuida da exclusão
mútua para você.
📚 Resumo: Módulo 3 – Abstrações de
Programação (Semáforos, Monitores e
Sincronização)
1. Semáforos
• Definição:
• Variável usada para controlar o acesso de múltiplos processos/threads a um
recurso compartilhado, evitando problemas de seção crítica.
• Tipos:
o Semáforo de contagem: Contagem arbitrária (Ex: 10 salas disponíveis).
o Semáforo binário: Valores 0 ou 1 (tipo "bloqueado" / "desbloqueado").
• Uso:
Prevenir condições de corrida (race conditions), mas não garante 100% de
segurança.
• Funções básicas:
o sem_init(sem_t *sem, int pshared, unsigned int value); →
Inicializar
o sem_wait(sem_t *sem); → Bloquear (aguardar recurso)
o sem_post(sem_t *sem); → Liberar (sinalizar recurso disponível)
• Exemplo:
Biblioteca com 10 salas de estudo → alunos = processos, salas = recurso,
recepcionista = semáforo.
2. Seção Crítica e Sincronização
• Seção Crítica:
Parte do programa onde o recurso compartilhado é acessado. Apenas um
processo/thread pode executá-la de cada vez.
• Problemas sem sincronização:
Condição de corrida → valores inesperados/errados devido à alternância de
processos.
• Técnica de sincronização:
Mutex (Mutual Exclusion):
o Bloqueia o acesso à seção crítica enquanto um processo a utiliza.
• Exemplo (Código com pthreads):
o pthread_mutex_init → inicializa mutex.
o pthread_mutex_lock → trava acesso antes da seção crítica.
o pthread_mutex_unlock → libera após a seção crítica.
o pthread_mutex_destroy → destrói o mutex ao final.
• Resultado esperado:
Job 1 started
Job 1 finished
Job 2 started
Job 2 finished
3. Monitor
• Definição:
Construção de alto nível para sincronização de processos.
• Características:
o Tipo de dado abstrato que encapsula variáveis compartilhadas +
procedimentos.
o Somente um processo pode executar dentro do monitor por vez
(exclusão mútua automática).
• Vantagens:
o Facilita o controle de acesso.
o Evita erros comuns ao usar semáforos diretamente.
o Mais seguro para aplicações complexas.
🧠 Mapa Mental: Abstrações de
Programação
+-------------------------------------+
| Abstrações de Programação |
+-------------------------------------+
|
+-----------------------+------------------------+
| | |
Semáforo Seção Crítica Monitor
| | |
+-----+------+ +-------+------+ +--------+---------+
| | | | | |
Tipos: Funções: Problemas: Solução: Definição:
Características:
- Contagem - sem_init - Corrida - Mutex - Tipo dado - 1
processo
- Binário - sem_wait (pthread) abstrato por
vez
- sem_post - Variáveis -
Procedimentos
Exemplo: Biblioteca Exemplo: Código compartilhadas
encapsulados
10 salas pthreads + procedimentos
1. Máquinas de Estado
Uma abordagem para organizar o fluxo de execução dentro de uma sub-rotina, onde o
estado é determinado pelo ponto atual de entrada e saída. Pode ser implementado
por recursão mútua e gera um código mais legível do que o uso de goto.
2. Modelo de Ator de Simultaneidade
Cada "ator" (como em videogames) possui seus próprios procedimentos e cede
voluntariamente o controle a um escalonador central, que executa todos de forma
sequencial. Esse modelo é uma forma de multitarefa cooperativa.
3. Comunicar Processos Sequenciais
Cada subprocesso é tratado como uma corrotina. As operações de I/O e bloqueio
geram corrotinas, e um planejador as desbloqueia quando eventos ocorrem.
Alternativamente, processos podem ser estruturados como geradores aninhados.
4. Comunicação Reversa
Comum em software matemático, onde um procedimento como um solucionador ou
avaliador integral precisa que o processo principal realize cálculos como avaliar
equações ou integrar funções.
5. Pthreads
Conceito de multithreading no contexto de processos:
• Processo: Agrupador de recursos (código e dados) com identidade própria e
normalmente um único fluxo de execução.
• Thread: Fluxos de execução dentro de um processo, compartilhando o mesmo
espaço de endereçamento, mas com seu próprio contador de programa, pilha
e registradores.
Vantagens das threads:
• Tratam atividades simultâneas.
• Dividem tarefas de forma eficiente.
• Reduzem o tamanho de aplicações.
• São mais rápidas para criar e destruir que processos.
• Permitem paralelismo real em sistemas multicore.
Pthreads é o padrão POSIX para threads, padronizando funções como criação
(pthread_t), configuração (pthread_attr_t) e gerenciamento de threads.
6. OpenMP
OpenMP é uma API de programação paralela para arquiteturas de memória
compartilhada (como SMPs e processadores multicore). Ele adiciona anotações
simples em programas C/C++ para descrever:
• Como o trabalho será dividido entre múltiplos threads.
• Como o acesso a dados compartilhados será tratado.
Pontos positivos do OpenMP:
• Portabilidade: Código multithreading pode ser rodado em diferentes
plataformas.
• Simplicidade: O programador escreve menos código paralelo; o compilador faz
grande parte do trabalho.
• Alta escalabilidade: Programas paralelos são otimizados para múltiplos
núcleos.
• Popularidade: Ampla aceitação no mercado devido à expansão dos hardwares
multithreading.
Importante: O OpenMP não é uma linguagem nova, mas sim uma forma de expandir
programas sequenciais existentes com paralelismo.
Abstract (Português)
• A computação distribuída é fundamental para o desenvolvimento de aplicações
de tecnologia atuais.
• O professor Sergio Rodrigues Affonso Franco discute a efetivação da
computação distribuída como campo de conhecimento na Ciência da
Computação.
Objetivos
• Compreender o funcionamento dos sistemas distribuídos no desenvolvimento
de aplicações paralelas, contribuindo para acelerar cargas de trabalho.
• Mensurar os impactos dos métodos aplicados para resolução de problemas em
sistemas distribuídos.
• Analisar os conceitos básicos dos paradigmas de comunicação, identificando
modelos para coordenação de tempo e garantia da transparência de
localização.
Conceitos Básicos dos Paradigmas de Comunicação
• A troca de mensagens é essencial em sistemas distribuídos devido à ausência
de memória física compartilhada.
• O modelo cliente/servidor é a base da computação distribuída, onde um cliente
submete requisições a um servidor que as processa.
• A comunicação assíncrona é utilizada para aumentar a escalabilidade, evitando
a espera por respostas remotas.
Comunicação em Grupo
• Coordenar sistemas distribuídos é desafiador devido a falhas de computadores,
inserção/remoção de máquinas e linhas de comunicação não totalmente
confiáveis.
• Chamadas de Procedimentos Remotos (RPC) envolvem apenas dois processos,
permitindo que programas chamem procedimentos em outras máquinas.
• A comunicação em grupos resolve o problema de limitações do RPC,
permitindo enviar mensagens a vários destinos simultaneamente.
Aplicações da Comunicação em Grupos
• Servidores altamente disponíveis e confiáveis, replicação de bancos de dados.
• Conferências multimídia e jogos distribuídos.
• Aplicações que necessitam de alta disponibilidade, confiabilidade e tolerância
a falhas.
Tipos de Comunicação em Grupo
• Multicast: Pacotes são enviados de uma só vez para todos os processos de um
grupo.
• Broadcast: Pacotes são enviados para todas as máquinas, masapenas os
processos do grupo os aceitam.
• Unicast: Transmissão ponto a ponto, com o processo enviando mensagens a
cada membro do grupo.
Grupos Fechados vs. Grupos Abertos
• Grupos fechados permitem que apenas membros enviem mensagens entre si,
usados geralmente para execução paralela.
• Grupos abertos permitem que qualquer processo envie mensagens para
qualquer grupo, comum em servidores replicados.
• Grupos podem ser pares (semelhantes) ou hierárquicos (com um coordenador).
Gerenciamento de Grupos
• O gerenciamento pode ser centralizado, com um servidor de grupo controlando
tudo, ou distribuído.
• Grupos abertos aceitam mensagens de fora anunciando presença, enquanto
grupos fechados exigem solicitação para participar.
• É crucial controlar a criação, destruição e participação de processos nos
grupos.
Atomicidade e Ordenação de Mensagens
• Atomicidade: Uma mensagem deve chegar a todos os membros do grupo ou a
nenhum.
• Ordenação de mensagens: As mensagens devem ser entregues na ordem
correta, usando buffer se necessário.
• Ferramentas como ZooKeeper são úteis para coordenar eventos e comunicação
em sistemas distribuídos.
Código Móvel
• Componentes de aplicações em sistemas distribuídos tradicionais são
estáticos, mas o código móvel permite transferir programas sob demanda.
• A mobilidade de código oferece flexibilidade no gerenciamento da configuração
e vantagens na execução de atividades distribuídas.
• Applets Java exemplificam o conceito, sendo pequenos programas executados
em navegadores.
Agentes Móveis e Segurança
• Agentes móveis migram autonomamente em um sistema distribuído,
suspendendo a execução na origem e retomando em outro local.
• A segurança é uma preocupação, com modelos como sandbox para execução
segura de código estrangeiro.
• O modelo ActiveX, por outro lado, usa autenticação por assinaturas digitais sem
sandbox.
Requisitos do Código Móvel
• Para ser móvel, o código deve ter abstração completa e não depender de
detalhes do sistema operacional ou hardware.
• A execução de programas de código móvel é feita sob demanda, exigindo
transmissão, instalação e execução rápidas e automáticas.
• Transmissão, instalação e execução eficientes garantem transparência e
desempenho aceitável.
Orientação a Eventos
• Um evento é uma mudança significativa de estado, cuja ocorrência pode ser
divulgada para outros aplicativos.
• A arquitetura orientada a eventos usa mensagens (notificações de evento) e
muitas vezes é projetada sobre arquiteturas orientadas a mensagens.
• Um sistema de mensagens é um mecanismo comum para troca de informações
entre aplicações.
Componentes de um Sistema Orientado a Eventos
• Emissores (agentes): Detectam, reúnem e transferem eventos, sem conhecer os
consumidores.
• Consumidores (coletores): Aplicam uma reação ao receber um evento, podendo
filtrar, transformar e encaminhar o evento.
• Canais de eventos: Transmitem eventos de emissores para consumidores,
implementados com middleware ou comunicação ponto a ponto.
Princípios de Integração de Aplicações
• Fracamente acoplado: Mínima dependência entre aplicações para que
modificações em uma não afetem a outra.
• Padrões de interfaces comuns: Formato de dados comum para troca de
mensagens entre aplicativos.
• Latência: Tempo para as mensagens passarem entre remetente e receptor,
devendo ser baixa.
Confiabilidade e Controle de Mensageria
• Confiabilidade garante que indisponibilidade temporária de aplicativos não
afete aplicações dependentes.
• Filas de mensagens são conectores que enviam/recebem mensagens entre
aplicações de forma oportuna e confiável.
• Mensagens são pacotes de dados transmitidos por uma rede para uma fila de
mensagens.
Remetente e Destinatário
• Remetente (produtor): Aplicativos que enviam dados para um destino,
estabelecendo conexões com a fila de mensagens.
• Destinatário (consumidor): Aplicativos que recebem dados das filas de
mensagens, extraindo e processando os dados.
• Protocolos de transmissão de dados: Regras para controle das trocas de
mensagens entre aplicativos, como AMQP, STOMP, MQTT e HTTP.
Modo de Transferência e Sistemas de Mensagens
• O modo de transferência define como os dados são transferidos de uma
aplicação de origem para a aplicação receptora (síncrono, assíncrono, em lote).
• Sistema de mensagens point-to-point (PTP): Mensagens são trocadas entre
remetentes e destinatários para um destino (fila), sendo consumidas por
apenas um destinatário.
• As mensagens são colocadas em uma fila na ordem em que são produzidas,
mas a ordem em que são consumidas depende de diversos fatores.
Sistema de Mensagens Publisher/Subscribe (Pub/Sub)
• Assinantes registram interesse em um tópico ou evento e são notificados
assincronamente.
• Um modelo de mensagem Pub/Sub é usado quando você precisa transmitir um
evento ou mensagem para muitos consumidores.
• Editores não têm conhecimento dos assinantes, e as mensagens são enviadas
sem necessidade de solicitação.
Funcionamento do Pub/Sub
• As mensagens são compartilhadas por meio de um canal chamado tópico.
• O editor não tem conhecimento de quais assinantes estão recebendo as
mensagens.
• Cada consumidor que assina um tópico recebe sua própria cópia das
mensagens publicadas nesse tópico.
Exemplo e Protocolo AQMP
• O modelo Pub/Sub é útil para notificar vários consumidores de um evento, sem
que o editor precise saber como as informações serão usadas.
• O Protocolo de Enfileiramento de Mensagens Avançado (AQMP) é um protocolo
aberto para enfileiramento de mensagens assíncronas.
• Em um sistema AQMP, produtores enviam mensagens aos brokers (corretores),
que as entregam aos consumidores.
Componentes do AQMP e Paradigmas de Comunicação
• Cada broker possui um componente chamado exchange (intercâmbio) que é
responsável por rotear as mensagens.
• O protocolo AQMP provê confiabilidade e garantia na entrega de mensagens
ordenadas.
• Para finalizar o módulo, é apresentado um vídeo sobre os paradigmas para
comunicação em computação distribuída.
Nomeação em Sistemas Distribuídos
• Nomes são fundamentais para compartilhar recursos e identificar entidades em
sistemas distribuídos.
• A nomeação estruturada implementa um sistema de resolução de nomes,
essencial para sistemas distribuídos.
• Entidades são acessadas por meio de um ponto (endereço), e os nomes são
organizados no conceito de espaço de nomes.
Independência de Localização e Identificadores
• Um nome independente de sua localização significa que o nome da entidade
não referencia seu endereço.
• Um nome amigável é usado por seres humanos, consistindo em cadeias de
caracteres de fácil entendimento.
• Um identificador referencia no máximo uma entidade, sempre a mesma,
permitindo referências sem ambiguidade.
Sistemas de Nomeação e DNS
• Um sistema de nomeação mantém uma vinculação nome-endereço.
• Em sistemas distribuídos de grande escala, tabelas descentralizadas são
necessárias, como no Domain Name Service (DNS).
• O DNS utiliza uma árvore hierárquica para a resolução de nomes, com serviços
de nome associados e distribuídos.
Resolução de Nomes no DNS
• Resolução iterativa: O servidor responde com o nome do próximo servidor a ser
buscado, e o cliente procura iterativamente.
• Resolução recursiva: O servidor passa o resultado para o próximo servidor, e o
cliente recebe a mensagem de endereço encontrado ou não.
• O DNS é o sistema de resolução de nomes da Internet, gerando uma base de
dados distribuída que localiza rapidamente entidades mapeadas.
Nomeação em Atributo e LDAP
• A nomeação em atributo fornece descrições a partir de pares (atributo, valor),
conhecidos como serviços de diretórios.
• Sistemas como LDAP (Protocolo Leve de Acesso a Diretório) implementam
hierarquias de nomeação baseadas em atributos.
•O serviço de diretório LDAP é organizado em registros (entrada de diretório),
compostos por um conjunto de pares (atributo, valor).
Distributed Hash Tables (DHT)
• As tabelas de Hash distribuídos (DHT) são sistemas descentralizados que
provêm um serviço de busca semelhante a uma tabela de Hash.
• A responsabilidade por manter o mapa dos atributos é distribuída entre os nós.
• DHTs são utilizados para nomeação em sistemas peer-to-peer, com
descentralização e alta escalabilidade.
Vídeo sobre Sistemas de Nomeação
• Apresentação de um resumo do módulo explicando sobre os sistemas de
nomeação e suas técnicas.
Sincronização de Relógios
• A sincronização entre processos locais é fundamental para a comunicação em
sistemas distribuídos.
• Semáforos e monitores não são recomendados para sistemas distribuídos
devido à ausência de memória compartilhada.
• Em sistemas distribuídos, conseguir acordo nos horários não é trivial.
Relógios Lógicos e Protocolo NTP
• Hosts possuem relógios físicos internos, mas é difícil manter todos os cristais
funcionando na mesma frequência.
• Cristian (1989) propôs usar um modelo cliente/servidor no qual clientes
consultam a hora em um servidor de tempo de precisão.
• O Protocolo de Tempo de Rede (NTP) ajusta-se em um modelo de pares de
servidores para entregar maior precisão de relógio.
Algoritmos Centralizados e Distribuídos para Exclusão Mútua
• Algoritmos centralizados elegem um coordenador para controlar o acesso à
região crítica, mas o coordenador é um único ponto de falha.
• Algoritmos distribuídos, como o de Ricart e Agrawala, requerem uma ordem
total dos eventos no sistema.
• O algoritmo de Lamport fornece um timestamp para a exclusão mútua
distribuída.
Algoritmo em Anel para Exclusão Mútua
• Um anel circular é construído, e cada processo está associado a uma posição
no anel.
• Um token circula pelo anel, permitindo que apenas o processo que o possui
entre na região crítica.
• Se o token for perdido, o mesmo deverá ser gerado novamente.
Algoritmos de Detecção de Deadlocks Distribuídos
• Um deadlock ocorre quando um conjunto de processos fica bloqueado
permanentemente, esperando um evento externo.
• Estratégias incluem evitar, prevenir ou detectar e recuperar de deadlocks.
• Algoritmos centralizados examinam o estado do sistema para determinar se
existe um deadlock e executam uma ação corretiva.
Algoritmo de Eleição
• Em sistemas distribuídos, diversos algoritmos necessitam que um processo
exerça uma função especial, como coordenador.
• A falha do coordenador compromete o serviço, e um novo coordenador deve
assumir através de uma eleição.
• Algoritmos comuns incluem o bully (valentão) e o ring (anel).
Algoritmo de Bully e Ring
• No algoritmo de Bully, um processo envia uma mensagem de eleição para todos
os processos com número maior que o seu.
• No algoritmo de Ring, os processos são ordenados e enviam uma mensagem de
eleição para seu sucessor.
• É apresentado um vídeo sobre os algoritmos para sincronização em sistemas
distribuídos.
Replicação de Dados
• A replicação de dados garante confiabilidade, desempenho e disponibilidade.
• A replicação síncrona garante que todas as réplicas estejam sincronizadas
globalmente, mas pode ser cara em termos de desempenho.
• Muitas soluções de banco de dados NoSQL aplicam consistência eventual,
tolerando um alto grau de inconsistência.
Interfaces de Programação Distribuída
• Com a explosão da Internet, as aplicações tiveram que se adaptar a uma nova
realidade de comunicação, tornando-se distribuídas.
• APIs facilitam as tarefas de comunicação e processamento, incluindo sockets,
MPI, RPC e barramento.
• Criar uma aplicação distribuída é uma tarefa muito importante nos dias atuais
devido a facilidade de acesso promovida com a difusão da Internet.
Programação em Sockets
• O termo socket refere-se à Interface de Programação de Aplicações (API)
implementada pelo grupo de distribuição de software UNIX da Universidade de
Berkeley (BSD).
• A troca de mensagens é feita entre dois processos, usando vários mecanismos
de transporte.
• Processos em sistemas diferentes podem se comunicar por meio dos sockets
somente se utilizarem o mesmo esquema de endereçamento.
Funções da API de Sockets
• getaddrinfo(): Traduz nomes para endereços.
• socket(): Cria um socket e retorna o descritor de arquivo.
• bind(): Associa o socket a um endereço socket e a uma porta.
Funções de Conexão e Comunicação em Sockets
• connect(): Tenta estabelecer uma conexão com um socket.
• listen(): Coloca o socket para aguardar conexões.
• accept(): Aceita uma nova conexão e cria um socket.
Funções de Envio e Recebimento em Sockets
• send(): Caso conectado, transmite mensagens ao socket.
• recv(): Recebe as mensagens por meio do socket.
• close(): Desaloca o descritor de arquivo.
Funções de Desativação e Sockets UDP
• shutdown(): Desabilita a comunicação do socket.
• Sockets UDP são canais não confiáveis, sem garantia de entrega, podendo
entregar datagramas duplicados e sem ordem.
• Funções para sockets UDP incluem DatagramSocket, receive, send e close.
Sockets TCP e Programação em Sockets
• Protocolo TCP implementa uma comunicação confiável com garantia de
entrega, ordenamento e não duplicação.
• Funções para sockets TCP incluem ServerSocket, accept e Socket.
• Para programar com sockets, usa-se uma arquitetura cliente/servidor,
implementando um programa cliente e um servidor que usam a API de sockets.
Lado Cliente e Lado Servidor em Sockets
• Lado cliente: Cria um socket, conecta-se ao servidor, envia e recebe mensagens
e fecha o socket.
• Lado servidor: Cria um socket, associa a uma porta, escuta novas conexões,
aceita conexões e envia/recebe mensagens.
• É apresentado um exemplo de implementação de um código para o lado cliente
em Python utilizando socket.
Exemplos de Código em Python e C para Servidor Socket
• Apresentação de um exemplo de código em Python utilizando socket para o
lado servidor.
• Apresentação de um exemplo de código em C para o lado servidor de um socket
para ambiente Linux.
Exemplo de Código em Python para Cliente Socket
• Apresentação de um exemplo de código em Python utilizando socket para o
lado cliente.
Exemplo de Código em C para Cliente Socket
• Apresentação de um exemplo de código em C para o lado cliente de um socket
para ambientes Linux.
Programação Paralela com MPI
• Programação paralela está relacionada ao uso de computadores com várias
unidades de processamento.
• O objetivo é transformar algoritmos complexos em tarefas menores executadas
simultaneamente.
• O paralelismo pode ser explorado de forma implícita ou explícita, usando APIs
como MPI.
MPI (Message Passing Interface)
• MPI é uma biblioteca com funções (API) para troca de mensagens, responsável
pela comunicação e sincronização de processos.
• O MPI define um conjunto de rotinas para facilitar a comunicação entre
processos em memória.
• O foco do MPI é disponibilizar uma interface para o desenvolvimento de
programas que utilizem troca de mensagens.
Comunicação e Sincronização em MPI
• Os processos podem usar mecanismos de comunicação ponto a ponto ou
coletiva.
• O MPI suporta comunicação assíncrona e programação modular por meio de
comunicadores.
• Um programa "Olá Mundo" (Hello World) em C apresenta a estrutura básica de
um programa MPI.
Comandos MPI_Init, MPI_Comm_size, MPI_Comm_rank e MPI_Finalize
• O comando MPI_Init inicializa o ambiente MPI para o processo.
• O comando MPI_Comm_size retorna o número total de processos criados.
• O comando MPI_Comm_rank retorna a identificação única do processo.
• O comando MPI_Finalize() encerra o ambiente MPI para esse processo.
Comunicação Síncrona e Assíncrona em MPI
• A comunicação síncrona (bloqueante) requer que o processador aguarde um
sinal de recebimento.• A comunicação assíncrona (não bloqueante) não espera por esse sinal.
• Apresenta-se um exemplo de código MPI bloqueante e não bloqueante.
Chamada a Procedimento Remoto (RPC)
• Sistemas distribuídos são baseados na troca de mensagens entre processos, e
as chamadas de procedimento remoto (RPC) são um pilar para sistemas
cliente/servidor.
• O princípio do RPC é estender a noção da chamada de procedimento local para
a chamada remota.
• Uma chamada de procedimento remoto é iniciada pelo cliente, que envia uma
mensagem para um servidor remoto para executar um procedimento.
Estrutura e Comunicação RPC
• No modelo RPC, um thread controla dois processos: cliente e servidor.
• O processo cliente envia uma mensagem ao servidor e aguarda uma resposta.
• Do lado do servidor, um processo aguarda uma mensagem do cliente,
processa-a e envia a resposta.
Considerações sobre RPC
• O protocolo RPC pode ser implementado sobre diferentes tipos de protocolos
de transporte.
• É a aplicação que precisa cuidar da confiabilidade, pois o RPC não implementa
nenhuma forma de garantir a entrega.
• É necessário um protocolo comum de representação dos dados para que
cliente e servidor possam se comunicar.
Mapeamento de Portas e Exemplos de Serviços RPC
• É necessário um protocolo para mapeamento das portas e os serviços
oferecidos, denominado mapeador de portas – portmapper.
• Exemplos de serviços que usam RPC incluem NFS (Network File Server) e NIS
(Network Information Service).
Desenvolvimento com Memória Compartilhada (Barramento)
• Sistemas de processamento simétrico (SMP) possuem de dois a sessenta e
quatro processadores, e são considerados uma arquitetura de memória
compartilhada.
• Cada processador tem acesso a toda a memória do sistema por meio de um
barramento ou rede de comunicação dedicada.
• A sincronização entre tarefas é feita por escrita/leitura na memória
compartilhada.
OpenMP
• O desenvolvimento de aplicações paralelas nesse modelo pode ser feito com a
biblioteca OpenMP.
• OpenMP é uma interface de programação (API) multithreading, portável,
baseada no modelo de programação paralela de memória compartilhada.
• É composta por diretivas de compilação, bibliotecas de execução e variáveis de
ambiente.
Funcionamento e Estrutura do OpenMP
• Todos os programas OpenMP iniciam como processo simples (thread mestre).
• O thread mestre cria um fork, gerando um conjunto de threads paralelos que
executam o código na região paralela.
• Todo o paralelismo do OpenMP é baseado em diretivas de compilação.
Exemplo de Código OpenMP
• No programa, deve ser definido o trecho que será paralelizado utilizando a
diretiva #pragma omp.
• Transforma-se um código sequencial em um código paralelizado com OpenMP.
• Existem diversas diretivas e técnicas de desenvolvimento para sincronização
com o OpenMP.
Vídeo sobre Interfaces de Programação Distribuída
• Apresentação de exemplos de programas que utilizam as APIs de programação
distribuída Socket, RPC, MPI e OpenMP.
Conclusão e Desafios
• A computação distribuída é amplamente utilizada no meio acadêmico e
empresarial.
• Desafios incluem identificar concorrência, compartilhar recursos de forma
segura, entregar um sistema de imagem única, segurança e desempenho.
• O aprofundamento nesses temas é fundamental para o crescimento na
computação distribuída.
Sistemas Distribuídos e Taxonomia de Flynn
Principais características dos sistemas distribuídos:
Taxonomia de Flynn
Lei de Amdahl e Speedup
Desafios e Benefícios dos Sistemas Distribuídos
1. Memória Compartilhada
1.1 Paralelização com OpenMP
2. Memória Distribuída
2.1 Paralelização com MPI
Paralelismo de Dados
Características:
Exemplo:
Importância da Localidade de Dados:
Paralelismo de Tarefas
Características:
Exemplo:
Comparação entre Paralelismo de Dados e Paralelismo de Tarefas
Conclusão
1. Arquitetura Mestre-Escravo
2. Polling
3. Redes Peer-to-Peer (P2P)
4. Clusters de Computadores
Identificação de Problemas e Soluções no Uso de Variáveis Compartilhadas
1. Conceitos Básicos
2. Modelos de Gerenciamento de Threads
3. Cálculo Não Determinístico e Condição de Corrida
4. Solução: Exclusão Mútua (Seções Críticas e Mutex)
5. Alternativa: Espera Ocupada
6. Uso de Memória Compartilhada entre Processos
Resumo Final
• 1. Condições de Corrida
• 2. Sincronização de Processos
• 3. Exclusão Mútua
• 4. Problemas Clássicos de Sincronização
• Produtor-Consumidor
• Leitores-Escritores
• Jantar dos Filósofos
• 5. Problemas Relacionados à Concorrência
• Deadlock
• Starvation (Fome)
• Inversão de Prioridade
• Espera Ocupada
• 6. Soluções para Condições de Corrida
• Operações Atômicas
• Locks e Mutexes
• Semáforos
1. Ignorando o Deadlock
2. Detecção de Deadlocks
3. Prevenção de Deadlocks
4. Algoritmos para Evitar Deadlocks
5. Deadlocks em Sistemas Distribuídos
o 🧠 Dica Final:
📚 Resumo: Módulo 3 – Abstrações de Programação (Semáforos, Monitores e Sincronização)
1. Semáforos
2. Seção Crítica e Sincronização
3. Monitor
🧠 Mapa Mental: Abstrações de Programação
1. Máquinas de Estado
2. Modelo de Ator de Simultaneidade
3. Comunicar Processos Sequenciais
4. Comunicação Reversa
5. Pthreads
6. OpenMP