Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas...

47
Sistemas Operacionais Programação Concorrente Sincronização entre processos Edson Moreno [email protected] http://www.inf.pucrs.br/~emoreno

Transcript of Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas...

Page 1: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Sistemas Operacionais

Programação ConcorrenteSincronização entre processos

Edson [email protected]

http://www.inf.pucrs.br/~emoreno

Page 2: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Sumário

Conceituação

Princípios de concorrência

Região crítica

Coordenação de Acesso à Região crítica

Page 3: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Introdução Threads são Processos leves

Definidos para permitir paralelismo em um programa de aplicação

As threads possuem Sua própria pilha de execução e program counter

Cada uma roda um código seqüencial (definido no programa de aplicação)

Podem criar processos (threads) filhos

Compartilham o mesmo espaço de endereçamento (dados globais) do processo pesado

Portanto, Quando uma thread altera um valor compartilhado, todas percebem esta mudança

Arquivos abertos por uma thread são disponível as outras do mesmo processo pesado.

Como manter a coerência dos dados? A partir do emprego de mecanismos de sincronização

Page 4: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Sumário

Conceituação

Princípios de concorrência

Região crítica

Coordenação de Acesso à Região crítica

Page 5: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Princípios de concorrência Exemplo 1

Algoritmo do produtor consumidor

Produtor: processo que gera n valores

Consumidor: consome os dados gerados pelo produtor

Meio de armazenamento: fila circular

Produtor Consumidor

Page 6: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Princípios de concorrência Exemplo 1 - Produtor consumidor

ProdutorConsumidor

#define N 10 #

int buffer[N], addrprod = 0, addrcons = 0 ;

void * produtor(){

int i, p=50;

for(i=0; i<20; i++) {

while(((addrprod + 1) % N) == addrcons){}

p++;

buffer[addrprod] = p ;

addrprod= ( addrprod + 1 ) % N ;

}

}

void * consumidor(){

int i, c;

for (i=0; i<20; i++){

while(addrprod == addrcons) {}

c = buffer[addrcons] ;

printf("Consumi o valor %d”,c);

printf(“Posição consimida %d”, addrcons);

addrcons= ( addrcons + 1 ) % N ;

}

}

Page 7: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Princípios de concorrência Exemplo 1 - Produtor consumidor

Cenário de execução

Se o consumidor for executado primeiro

Buffer está vazio

Produtor ainda não gerou valores

Processador ficará preso fazendo while

Produtor Consumidor

void * consumidor(){

int i, c;

for (i=0; i<20; i++){

while(addrprod == addrcons) {}

c = buffer[addrcons] ;

printf("Consumi o valor %d”,c);

printf(“Posição consimida %d”, addrcons);

addrcons= ( addrcons + 1 ) % N ;

}

}

Page 8: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Princípios de concorrência Exemplo 1 - Produtor consumidor

Produtor Consumidor

void * produtor(){

int i, p=50;

for(i=0; i<20; i++) {

while(((addrprod + 1) % N) == addrcons){}

p++;

buffer[addrprod] = p ;

addrprod= ( addrprod + 1 ) % N ;

}

}

Cenário de execução

Quando o produtor for executado

Executa o comando while

Começa a inserir valores no buffer

Posição de deposito é incrementado

Tratamento para buffer circular

Processo se repete até a thread perder o

processador

Page 9: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Sumário

Conceituação

Princípios de concorrência

Região crítica

Coordenação de Acesso à Região crítica

Page 10: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica

Ocorre quando

Sistema composto por N processos (onde N > 1)

Cada processo executa seu próprio código independente dos demais

Processos compartilham um dado recurso

O estado de um processo é desconhecido pelo outro

O estado/valor do recurso pode ser alterado

Page 11: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Exemplo

Thread 0 Thread 1a

void * t0(){

long i ;

for (i=0; i<1000000; i++){

a = a + 5 ;

}

printf("Encerrei a t0 %d\n",sizeof(int));

}

void * t1(){

long i ;

for (i=0; i<1000000; i++){

a = a + 2;

}

printf("Encerrei a t1\n");

}

Page 12: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Exemplo

Supondo a com valor inicial 60 e a seguinte linha de tempo

T0: Thread0 executa load a e perde o processador: o valor do acumulador (60) é salvo.

Thread 0 Thread 1a = 60

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 5 ; // adicionar 5 ao acumulador

store a ; // armazenar na variável a

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 2 ; // adicionar 2 ao acumulador

store a ; // armazenar na variável a

Page 13: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Exemplo

Supondo a com valor inicial 60 e a seguinte linha de tempo

T0: Thread0 executa load a e perde o processador: o valor do acumulador (60) é salvo.

T1: Thread1 ganha o processador e executa load a: o valor do acumulador é 60 .

Thread 0 Thread 1a = 60

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 5 ; // adicionar 5 ao acumulador

store a ; // armazenar na variável a

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 2 ; // adicionar 2 ao acumulador

store a ; // armazenar na variável a

Page 14: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Exemplo

Supondo a com valor inicial 60 e a seguinte linha de tempo

T0: Thread0 executa load a e perde o processador: o valor do acumulador (60) é salvo.

T1: Thread1 ganha o processador e executa load a: o valor do acumulador é 60 .

T2: Thread1 executa add 2: o valor do acumulador é 62.

Thread 0 Thread 1a = 60

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 5 ; // adicionar 5 ao acumulador

store a ; // armazenar na variável a

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 2 ; // adicionar 2 ao acumulador

store a ; // armazenar na variável a

Page 15: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Exemplo

Supondo a com valor inicial 60 e a seguinte linha de tempo

T0: Thread0 executa load a e perde o processador: o valor do acumulador (60) é salvo.

T1: Thread1 ganha o processador e executa load a: o valor do acumulador é 60 .

T2: Thread1 executa add 2: o valor do acumulador é 62.

T3: Thread1 executa store a: o valor do acumulador é armazenado na variável.

Thread 0 Thread 1a = 62

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 5 ; // adicionar 5 ao acumulador

store a ; // armazenar na variável a

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 2 ; // adicionar 2 ao acumulador

store a ; // armazenar na variável a

Page 16: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Exemplo

Supondo a com valor inicial 60 e a seguinte linha de tempo

T0: Thread0 executa load a e perde o processador: o valor do acumulador (60) é salvo.

T1: Thread1 ganha o processador e executa load a: o valor do acumulador é 60 .

T2: Thread1 executa add 2: o valor do acumulador é 62.

T3: Thread1 executa store a: o valor do acumulador é armazenado na variável.

T4: Thread0 ganha o processador, o valor do acumulador é restaurado (60) e executa a

operação add 5: o valor do acumulador passa a ser 65.

Thread 0 Thread 1a = 62

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 5 ; // adicionar 5 ao acumulador

store a ; // armazenar na variável a

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 2 ; // adicionar 2 ao acumulador

store a ; // armazenar na variável a

Page 17: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Exemplo

Supondo a com valor inicial 60 e a seguinte linha de tempo

T0: Thread0 executa load a e perde o processador: o valor do acumulador (60) é salvo.

T1: Thread1 ganha o processador e executa load a: o valor do acumulador é 60 .

T2: Thread1 executa add 2: o valor do acumulador é 62.

T3: Thread1 executa store a: o valor do acumulador é armazenado na variável.

T4: Thread0 ganha o processador, o valor do acumulador é restaurado (60) e executa a

operação add 5: o valor do acumulador passa a ser 65.

T5: Thread0 executa store a o valor do acumulador é armazenado na variável a (60).

Thread 0 Thread 1a = 65

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 5 ; // adicionar 5 ao acumulador

store a ; // armazenar na variável a

PRESSUPONDO O SEGUINTE ASSEMBLY GERADO

load a ; // carregar a no acumulador

add 2 ; // adicionar 2 ao acumulador

store a ; // armazenar na variável a

Page 18: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Solução para o problema

Emprego de protocolos de entrada e saída na região crítica

Sinaliza-se a entrada na região crítica

Opera-se sobre a região crítica

Sinaliza-se a saída da região crítica

A abordagem deve garantir que

Ao entrar, somente 1 processo execute/acesse a região crítica

Ao sair, permite que outro processo entre na seção crítica

Page 19: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Região crítica Requisitos para solução do problema

Exclusão mútua

A somente um processo por vez é permitido entrar na seção crítica;

Progresso

Deve ser permitido a um processo entrar na sua seção crítica se nenhum outro

processo está usando a seção crítica

Espera limitada

Um processo não pode ficar indefinidamente esperando para entrar na seção

crítica, enquanto outros processos, repetidamente, entram e saem de suas

respectivas seções críticas.

Page 20: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Sumário

Conceituação

Princípios de concorrência

Região crítica

Coordenação de Acesso à Região crítica

Page 21: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Solução por Hardware

Desabilitar interrupções

Nada interrompe as instruções em operação

Instruções implementadas por hardware

test-and-set (atômicas)

Page 22: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Test And Set

Exclusão mútua

Arquiteturas de processador com instrução TAS (Test And Set)

Lê posição de memória e atualiza os bits de estado

Escreve na posição de memória o conteúdo de um registrador

Leitura e escrita

Realizadas atomicamente

function Test_And_Set (var lock : boolean): boolean;

begin

Test_And_Set := lock;

lock := true;

end;

Page 23: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Produtor Consumidorwhile (cond) {

dado = produz();

while (contador == n);

enter();

buffer[novo] = dado;

novo = (novo+1) mod n;

contador++;

leave();

}

while (cond) {

while (contador == 0);

enter();

dado = buffer[prox];

prox = (prox+1) mod n;

contador--;

leave();

consome(dado);

}

Test And Set

Exclusão mútua entre consumidor e produtor, com a instrução TAS

enter testa uma variável, lock se

lock = 1, entrada na seção crítica permitida

lock = 0, espera até que lock = 1

Page 24: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

ENTER: MOV #0,R1

TAS R1,LOCK

JZ ENTER

RET

LEAVE: MOV #1,R1

STORE R1,LOCK

RET

Test And Set

Esta solução é chamada espera ociosa

Processo em leave mantém o processador desnecessariamente

Má utilização do tempo do processador

Page 25: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Solução por software

Algoritmo de Dekker

Implementação deDjikstra Propôs série de soluções evolutivas

Cada uma evidencia bugs comuns em programas concorrentes

1 - uma variável

2 - duas variáveis

3 - três variáveis

4 - correta

Algoritmo de Peterson garante

Exclusão mútua

Justiça para 2 processos

Page 26: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

.

.

.while turn <> 0 do { nothing };

< região crítica >

turn := 1;...

Processo 0...while turn <> 1 do { nothing };

< região crítica >

turn := 0;...

Processo 1

variável global compartilhada => turn: 0..1;

Primeira Tentativa Espera ociosa(busy-waiting) => while

Alternância explícita dos processos

Velocidade ditada pelo mais lento

Problema da solução?

Page 27: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

.

.

.while turn <> 0 do { nothing };

< região crítica >

turn := 1;...

Processo 0...while turn <> 1 do { nothing };

< região crítica >

turn := 0;...

Processo 1

variável global compartilhada => turn: 0..1;

Primeira Tentativa Espera ociosa(busy-waiting) => while

Alternância explícita dos processos

Velocidade ditada pelo mais lento

Problema da solução?

Espera ociosa e Intertravamento (um proc. pode necessitar mais acesso)

Page 28: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

.

.

.while flag[ 1 ] do { nothing };

flag[ 0 ] := true;

< região crítica >

flag[ 0 ] := false;...

Processo 0...while flag[ 0 ] do { nothing };

flag[ 1 ] := true;

< região crítica >

flag[ 1 ] := false;...

Processo 1

variável global compartilhada => var flag: array [0..1] of boolean;

Segunda Tentativa Cada processo

Tem sua própria chave para a RC

Vê o quadro de avisos do outro mas não pode alterá-lo

Não existe bloqueio se outro processo falha fora da Região crítica

Problema da solução?

Page 29: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

.

.

.while flag[ 1 ] do { nothing };

flag[ 0 ] := true;

< região crítica >

flag[ 0 ] := false;...

Processo 0...while flag[ 0 ] do { nothing };

flag[ 1 ] := true;

< região crítica >

flag[ 1 ] := false;...

Processo 1

variável global compartilhada => var flag: array [0..1] of boolean;

Segunda Tentativa Cada processo

Tem sua própria chave para a RC

Vê o quadro de avisos do outro mas não pode alterá-lo

Não existe bloqueio se outro processo falha fora da Região crítica

Problema da solução?

Pode não garantir exclusão mútua (flags inicializadas em false)

Page 30: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

.

.

.flag[ 0 ] := true;

while flag[ 1 ] do { nothing };

< região crítica >

flag[ 0 ] := false;...

Processo 0...flag[ 1 ] := true;

while flag[ 0 ] do { nothing };

< região crítica >

flag[ 1 ] := false;...

Processo 1

Terceira Tentativa Em relação à segunda tentativa, apenas uma mudança no código

Ponto de inicialização da intenção de acesso à região crítica

Garante exclusão mútua

Cada processo pode ativar o valor de seu flag sem saber da condição do outro

Problema da solução?

Page 31: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

.

.

.flag[ 0 ] := true;

while flag[ 1 ] do { nothing };

< região crítica >

flag[ 0 ] := false;...

Processo 0...flag[ 1 ] := true;

while flag[ 0 ] do { nothing };

< região crítica >

flag[ 1 ] := false;...

Processo 1

Terceira Tentativa Em relação à segunda tentativa, apenas uma mudança no código

Ponto de inicialização da intenção de acesso à região crítica

Garante exclusão mútua

Cada processo pode ativar o valor de seu flag sem saber da condição do outro

Problema da solução?

Propenso a deadlock

Page 32: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Quarta Tentativa

Processos indicam intenção de acesso à região crítica via flag

Problema da solução?

flag[0] =

flag[1] =FALSE

FALSE

.

flag[1] := true;

while flag[0] do

begin

flag[1] := false;

<pequena latência>;

flag[1] := true;

end;

< região crítica >;

flag[1] := false;

.

Process 1.

flag[0] := true;

while flag[1] do

begin

flag[0] := false;

<pequena latência>;

flag[0] := true;

end;

< região crítica >;

flag[0] := false;

.

Process 0

P1 sets flag [1] to true

TRUEP1 sets flag [1] to false

FALSE

PO sets flag [0] to true

TRUEP0 sets flag [0] to false FALSE

P0 sets flag [0] to true

TRUE

flag[0] := true; flag[1] := true;

flag[1] := false;

flag[0] := true;

flag[0] := false; flag[1] := false;

flag[1] := true;

while flag[1] do

flag[0] := true; flag[1] := true;flag[0] := true;

P0 checks flag [1]

P1 checks flag [0]

P1 sets flag [1] to true

TRUE

while flag[0] do

flag[0] := false;

while flag[1] do while flag[0] do

Page 33: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Quarta Tentativa Solução é quase correta

Gentileza mútua Possibilidade dos processos cederem a vez um para o outro indefinidamente

Pode acarretar em adiantamento indefinido (livelock)

Na prática

Situação difícil de se sustentar durante um longo tempo

Velocidade dos processos

Na teoria

Existe a probabilidade de ocorrer, logo

Invalida a proposta como solução geral do problema

Page 34: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

var flag: array [0 .. 1] of boolean;

turn: 0 .. l;

procedure P0;

begin

repeat

flag [0] := true;

while flag [1] do

if turn = 1 then

begin

flag [O] := false;

while turn = 1 do {nothing};

flag [0] := true

end;

< região crítica >;

turn := 1;

flag [0] := false;

< restante >

forever

end;

procedure Pl;

begin

repeat

flag [1] := true;

while flag [0] do

if turn = 0 then

begin

flag [1] := false;

while turn = 0 do {nothing};

flag [1] := true

end;

< região crítica >;

turn := 0;

flag [1] := false;

< restante >

forever

end;

Begin

flag [0] := false;

flag [1] := false;

turn := 1;

parbegin

P0; P1

parend

end.

Solução Correta de Dekker

Garante exclusão mútua e justiça

Usa flags (intenção de acesso) e turn (direito de acesso)

Page 35: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Solução de Peterson

Proposta em 1981

Solução simples e elegante para o problema da exclusão mútua

Facilmente generalizada para o caso de n processos

A solução do algoritmo consiste em

Ao marcar a sua intenção de entrar na região crítica, o processo já

indica (para o caso de empate) que a vez é de um outro

Page 36: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

var flag array [0 ..1] of boolean;

turn:0..1;

procedure P0;

begin

repeat

flag [0] := true;

turn := 1;

while flag [1] and turn = 1 do

{nothing};

< região crítica >;

flag [0] := false;

< restante >

forever

end;

procedure Pl;

begin

repeat

flag [1] := true;

turn := 0;

while flag [0] and turn = 0 do

{nothing};

< região crítica >;

flag [1] := false;

< restante >

forever

end; begin

flag [0] := false;

flag [1] := false;

turn := 1;

parbegin P0; P1 parend

end.

Algoritmo de Peterson

Garante exclusão mútua e justiça

Usa flags (intenção de acesso) e turn (direito de acesso)

Page 37: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Solução por software: Semáforo Semáforo

Semáforos são usados para exclusão mútua

Um semáforo s é uma estrutura de dados, formada por

Um contador

Um apontador para uma fila de processos bloqueados no semáforo

Somente pode ser acessado por duas operações atômicas

Se dois processos tentam acessar ou liberar uma região simultaneamente

Essas operações serão seqüencializadas

Page 38: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Primitivas

struct semaphore {int count;queueType queue;

}

void semWait(semaphore s){ // função Ps.count--;if(s.count<0){

1. Coloca o processo na lista de espera (s.queue)2. Bloqueia o processo

}}

void semSignal(semaphore s){ // função Vs.count++;if(s.count<=0){

1. Remove um processo P da lista de espera (s.queue)2. Coloca o processo P na lista de pronto

}}

Semáforo (Pthreads)

Page 39: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Fluxo de acesso à região crítica quando do emprego de semáforos

Semáforo (Pthreads)

Page 40: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

• Permite:

• Controlar o fluxo de controle do programa e

• Acessar a áreas de dados compartilhadas por threads concorrentes

• Especificar um número determinado de threads que podem entrar na seção

crítica

• Exemplo

• Fila para pegar passagem no aeroporto com 5 caixas, quando uma caixa fica

livre outro cliente pode ser tratado, mas somente 5 clientes podem ser

tratados concorrentemente

Semáforo (Pthreads)

Page 41: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Semáforo (Pthreads) Principais operações

int sem_init(sem_t *sem, int pshared, unsigned int value);

Inicializa um semáforo

Parâmetros

sem: Objeto semáforo a ser inicializado

pshared: Se diferente de zero indica que o semaforo pode ser compartilhado entre processos pesados

Value: Valor de inicialização do contador do semáforo

int sem_wait(sem_t * sem);

Decrementa o valor do semáforo

Se o valor do semáforo for negativo então

O processo que chamou o comando wait é bloqueado

Senão

O processo acessa a região crítica

Page 42: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Semáforo (Pthreads) Principais operações int sem_trywait(sem_t * sem);

Decrementa o valor do semáforo somente se este não estiver com valor negativo

Retorna 0 (zero) se o valor do semáforo não for negativo

O processo que chamou o comando wait é bloqueado

Senão

O processo que chamou não é bloqueado

int sem_post(sem_t * sem);

Incrementa o valor do semaforo

Move um processo da lista de bloqueados para a lista de pronto, se houve

int sem_getvalue(sem_t * sem, int * sval);

Captura o valor atual do semáforo e armazena em sval

int sem_destroy(sem_t * sem);

Elimina o controle dado pelo semáforo

Page 43: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

#include <pthread.h>#include <semaphore.h>

sem_t s0, s1;int buffer;

void main() {pthread_t tid1, tid2;sem_init(&s0, 0, 1);sem_init(&s1, 0, 0);pthread_create(&tid1, NULL, produtor, NULL);pthread_create(&tid2, NULL, consumidor, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);

}

void *produtor() {int i;for(i=0; i<100; i++) {sem_wait(&s0);buffer = i;sem_post(&s1);

}}

void *consumidor() {int i, k;for(i=0; i<100; i++) {sem_wait(&s1);k = buffer;sem_post(&s0);printf("Valor consumido: %d\n", k);

}}

Semáforo (Pthreads) – prod cons

Page 44: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Mutex (Pthreads) Utilizado para :

Proteger estruturas de dados compartilhadas em modificações concorrentes

Implementar seções críticas e monitores

Similar a um semáforo, mas que só pode assumir dois valores

Locked: Bloqueia o acesso a uma dada região crítica

Unlocked: Libera o acesso a uma dada região crítica

Cenário de operação com mutex

Uma thread que deseja fazer lock em mutex que já está com lock por outra

thread é suspenso até que a thread faça o unlock do mutex primeiro

Page 45: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Principais Operações int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex-attr_t *mutexattr);

Inicializa os valores do multiplexador

Parametros:

Mutex: objeto mutex

Mutexattr:

Objeto mutex_t pode ser inicializado estaticamente na criação com o comando

pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;

int pthread_mutex_lock(pthread_mutex_t *mutex);

Impede o acesso de outros processo à região crítica.

Se região estiver bloqueada, o processo chamador é suspenso

int pthread_mutex_trylock(pthread_mutex_t *mutex);

Tenta impedir o acesso de outros processo à região crítica.

Se região já estiver bloqueada, o processo chamador não é bloqueado

Mutex (Pthreads)

Page 46: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

Mutex (Principais Operações)

int pthread_mutex_unlock(pthread_mutex_t *mutex);

Libera o acesso à região crítica

int pthread_mutex_destroy(pthread_mutex_t *mutex);

Destroy o controle dado pelo objeto mutex

Mutex (Pthreads)

Page 47: Sistemas Operacionais - inf.pucrs.bremoreno/undergraduate/CC/sisop/class_files/Aula...Sistemas Operacionais Programação Concorrente Sincronização entre processos ... Compartilham

#include <stdio.h>#include <stdlib.h>#include <pthread.h>int saldo = 100;pthread_mutex_t m;

void * deposita( void *str ) {int i, a;for(i=0; i<100; i++) {

pthread_mutex_lock(&m);a = saldo; a = a + 1; saldo = a;pthread_mutex_unlock(&m);

}}

void * retira( void *str ) {int i, b;for (i=0; i<100; i++) {

pthread_mutex_lock(&m);b = saldo;b = b - 1;saldo = b;pthread_mutex_unlock(&m);

}}

void main() {pthread_t thid1, thid2;pthread_mutex_init(&m, NULL);

pthread_create (&thid1, NULL, deposita, NULL) != 0);pthread_create (&thid2, NULL, retira, NULL) != 0);

pthread_join(thid1, NULL);pthread_join(thid2, NULL);

printf(“SALDO ATUAL = %d\n”, saldo);}

Mutex (Pthreads) – Exemplo