• Nenhum resultado encontrado

Fundamentos de Sistemas Operacionais

N/A
N/A
Protected

Academic year: 2022

Share "Fundamentos de Sistemas Operacionais"

Copied!
37
0
0

Texto

(1)

Fundamentos de Sistemas Operacionais

Aula 4: Programação Concorrente

Diego Passos

(2)

Últimas Aulas

(3)

Processos

Compostos por:

Código (programa).

Estado (memória, registradores).

Em um sistema com multiprogramação:

Vários processos residentes em memória.

Várias aplicações rodam simultaneamente.

"Processo é um programa em execução".

Exemplo de um único programa que usa mais de um processo.

Função fork().

(4)

Threads

(5)

Threads

Similares a processos.

"Processos leves".

Definem uma "linha de execução" em um programa.

Sequência de instruções a serem executadas.

Diferença entre processo e thread: espaço de endereçamento.

Processos diferentes têm espaços de endereçamento diferentes.

Threads diferentes (de um mesmo processo)

compartilham o mesmo espaço de endereçamento.

Memória compartilhada.

(6)

Threads (mais)

Toda thread pertence a um processo.

O conceito de thread não existe sem o conceito de processo.

Todo processo tem ao menos uma thread.

Uma sequência de instruções a serem executadas.

(7)

Vantagens e Desvantagens

Threads são mais "leves".

Mudança de contexto entre duas threads do mesmo processo é rápida.

Poucas informações de estado para salvar/restaurar.

Threads (de um mesmo processo) compartilham memória.

Comunicação é mais fácil que entre processos.

Porém, uma thread pode interferir na execução da outra.

Os erros em uma podem se propagar para as outras.

Programas podem ser mais difíceis de depurar.

(8)

Programação Concorrente

(9)

Definição

Utilização de mais de uma "linha de execução" em um mesmo programa.

Vários processos para um único programa.

e.g., utilizando a função fork().

Várias threads em um mesmo processo.

Ou uma mistura dos dois.

Exemplo:

Servidor web tem um processo principal que espera conexões dos usuários.

Para cada nova conexão, é criado um novo processo (ou thread).

Processo (thread) principal volta a esperar por conexões.

(10)

Programa Paralelo vs. Sequencial

Programa Sequencial:

Uma única linha de execução.

Um processo com uma thread.

Programa Paralelo:

Múltiplas linhas de execução.

Vários processos ou threads.

Outro nome para a Programação Concorrente.

(11)

Objetivos da Programação Concorrente

Permite a separação lógica das funcionalidades de um programa.

Espera por conexões.

Atendimento aos clientes.

Simplifica a escrita de alguns programas.

Existem programas intrinsecamente paralelos.

Melhora a utilização dos processadores modernos.

Vários núcleos.

Ambientes multiprocessados.

Operações de E/S são sobrepostas com processamento.

(12)

Sobreposição de Operações de E/S

Versão Paralela (Concorrente) Versão Sequencial

(13)

Desvantagens da Programação Concorrente

Coordenação dos processos (threads) pode ser complexa.

Em termos de programação.

Erros "não-intuitivos" ocorrem.

Principalmente com threads.

É comum fazer suposições inválidas:

e.g, processos executam na mesma "velocidade".

Condições de erro são difíceis de reproduzir.

Depuração de programas paralelos tende a ser mais difícil.

Ordem de execução dos processos (threads) é imprevisível.

(14)

Tipos de Paralelismo

Paralelismo Real:

Ocorre apenas em máquinas multiprocessadas.

Processos (threads) são executados realmente simultaneamente.

Paralelismo aparente:

Ocorre em maquinas monoprocessadas.

Processos (threads) são executados concomitantemente.

(15)

Especificação de Paralelismo

(16)

Diferentes Representações

Sintaxe de criação de um programa paralelo depende do sistema.

Chamadas podem ser ligeiramente (ou extremamente) diferentes em SOs diferentes.

Porém, existem tipos "gerais" de especificação de paralelismo.

(17)

Paralelismo Explícito

Paralelismo é descrito explicitamente no programa.

Três funcionalidades básicas:

Criação de um processo (thread): create_process().

Encerramento de um processo (thread): exit().

Espera pelo encerramento de um processo (thread):

wait_process().

(18)

Paralelismo Explícito (Exemplo)

int main() {

f1 = create_process(codigo_filho);

f2 = create_process(codigo_filho);

wait_process(f1);

wait_process(f2);

return(0);

}

void codigo_filho() {

printf("Alguma coisa\n");

exit();

}

(19)

Paralelismo Implícito

Programador apenas indica quais "regiões" são paralelizáveis.

Compilador é responsável por criar os respectivos processos (threads).

Dois comandos básicos:

Parbegin (início da região paralela).

Parend (fim da região paralela).

(20)

Paralelismo Implícito (Exemplo)

int main() { Parbegin

codigo_filho();

codigo_filho();

Parend return(0);

}

void codigo_filho() {

printf("Alguma coisa\n");

exit();

}

Função codigo_filho() é executada duas vezes.

Mas por dois processos (threads) diferentes.

(21)

Paralelismo Implícito vs. Explícito

A versão explícita é mais comum.

Em geral, as chamadas de sistema são deste tipo.

e.g., função fork().

Há algumas linguagens (e compiladores) que implementam o paralelismo implícito.

Exemplo: biblioteca OpenMP.

Paralelismo implícito é mais simples.

Programador não se preocupa com como os processos (threads) são alocados.

Paralelismo explícito é mais flexivel.

Programador tem total controle sobre os processos (threads).

(22)

Grafo de Precedência

Algumas vezes, é preciso garantir a ordem em que certos eventos ocorrem em um programa paralelo.

Exemplo:

Garantir que o primeiro processo filho só morra após o início do segundo processo filho.

Nem sempre é fácil nas representações implícita e explícita.

Envolve a utilização de comunicação entre os processos (threads) filhos.

(23)

Grafo de Precedência (Exemplo)

(24)

Compartilhamento de

Recursos

(25)

Recursos Comuns

Processos (threads) de um programa paralelo geralmente compartilham recursos.

Variáveis.

Arquivos.

Sockets.

...

Estes recursos, em geral, estão ligados à comunicação entre processos (threads) do programa paralelo.

(26)

Compartilhamento de Memória

Tipo mais comum de recurso compartilhado.

Threads compartilham todo o espaço de endereçamento.

Processos podem requisitar do SO uma área de memória compartilhada.

Processos (threads) alteram o valor de variáveis compartilhadas para trocar informações.

e.g., segundo processo filho pode alterar a variável inicio_filho_2 de 0 para 1 para informar iniciou seu processamento.

(27)

Produtor-Consumidor

Aplicação comum em vários sistemas.

Há processos (threads) produtores.

Geram dados quaisquer.

Há um processo (thread) consumidor.

Pega dados dos produtores e realiza alguma operação.

Exemplo: servidor impressão.

Processos (threads) geram dados a serem impressos.

Um único processo é responsável por coletar os dados e realizar a operação de E/S de impressão.

Múltiplas impressões podem ser requisitadas simultaneamente.

(28)

Produtor-Consumidor (Funcionamento)

Há uma região de memória compartilhada por todos.

Spool de impressão.

Em geral, é um Buffer Circular.

Ao adicionar um novo elemento, produtor avança o ponteiro do próxima posição livre.

Ao coletar um dado, consumidor

avança ponteiro da próxima posição livre.

(29)

Região (Ou Seção) Crítica

(30)

Definição

É um trecho de código de um programa.

Especial, pois alguma manipulação de variável compartilhada acontece ali.

Em outras palavras:

É um trecho de um programa paralelo no qual existe acesso a variáveis compartilhadas entre dois ou mais processos (threads).

(31)

Importância da Região Crítica

A ordem de execução dos processos (threads) é imprevisível.

Acessos concorrentes podem causar problemas.

Exemplo:

Considere 'x' uma variável compartilhada por duas threads.

Seu valor inicial é 0

Qual o valor final de 'x'?

Thread 1:

x = x + 1;

Thread 2:

x = x + 1;

(32)

Importância da Região Crítica (mais)

O trecho executado pelas threads em assembly se torna:

MOVE x, ACC ADD ACC, 1 MOVE ACC, x

Suponha que a Thread 1 começa a execução, porém é interrompida imediatamente antes da segunda instrução.

A Thread 2 começa sua execução, lendo o valor de 'x' da memória.

Valor ainda é 0.

Thread 1 foi interrompida antes que pudesse armazenar em memória o novo valor de 'x'.

Ao final das execuções, x = 1.

(33)

Outro Exemplo: Produtor-Consumidor

Suponha dois produtores simultâneos.

P1 insere "Dado 3" na próxima posição livre.

Mas é interrompido antes de atualizar o ponteiro.

P2 executa e insere "Dado 4"

na posição antiga do ponteiro.

"Dado 3" é sobreescrito.

(34)

Condição de Corrida

Problema decorrente da execução simultânea de múltiplos processos na seção crítica.

Resultados inesperados (e diferentes) ocorrem.

O resultado depende da ordem de execução dos processos (threads).

Operações não são atômicas.

Como solucionar?

Evitar que processos (threads) diferentes possam estar na região crítica simultaneamente.

Conhecido como Exclusão Mútua.

Tornar operações sobre recursos compartilhados atômicas.

(35)

Operação Atômica

Operação que não pode ser interrompida.

Exemplo: a execução de uma única instrução de máquina é atômica.

Não há como interromper a operação uma vez que ela tenha sido iniciada.

Se a manipulação de uma região compartilhada de memória é atômica, não há condição de corrida.

(36)

Revisão

(37)

Para Lembrar

Definição de Programação Concorrente.

Tipos de paralelismo.

Real, aparente.

Representações implícita e explícita de paralelismo.

Razões para adoção de paralelismo.

Ordem de execução de um programa paralelo é imprevisível.

Não se pode fazer suposições.

Compartilhamento de recursos.

Recursos típicos.

Razões para compartilhar.

O que é região (seção) crítica é qual a sua importância.

O que é uma condição de corrida.

O que é exclusão mútua.

O que é uma operação atômica.

Referências

Documentos relacionados

diferentes filas para diferentes tipos de processos podendo os processos mudarem de fila em tempo de execução.. Cenários de uso

 A disciplina visa familiarizar o aluno com os principais subsistemas de gerência de recursos que compõem um sistema operacional..  Compreender os conceitos de

Consideramos que a linguagem como forma ou processo de interação é a concepção mais adequada para o ensino de Língua Portuguesa na escola, visto que, a partir dela,

Desenvolvimento de Sistemas Operacionais: projeto lógico, arquitetura, inicialização de Sistemas Computacionais, componentes (processos, threads, escalonador, mecanismos

salvaguardam de erros manifestos na submissão das ordens e que poderão tomar a.. 4 forma de rejeição da ordem ou desencadear os mecanismos de interrupção da

● Quando um novo processo é criado, SO procura por um bloco de memória física livre grande o suficiente para acomodar o novo processo.. ○ O início do bloco é alocado

Exu Meia-Noite Xangô Pedra Preta intermediário para Yorimá Exu Quebra Pedra Xangô 7 Cachoeiras intermediário para Yori Exu Ventania Xangô 7 Pedreiras intermediário

 Quando um processo é trocado por outro para execução, o sistema operacional deverá fazer o troca de contexto (ou. chaveamento de contexto) para o novo processo