LEIC/LERC 2009/10

Sistemas Operativos

Aula 3

Tarefas e Mecanismos de Sincronização

 

Objectivo

 


Introdução

1. Criação de tarefas

a) Copie o ficheiro aula3-eg1.tgz para a sua área de trabalho e descomprima o seu conteúdo:

  tar -zxvf aula3-eg1.tgz

b) Estude, compile e execute a aplicação. Compreenda o resultado (slide).

c) Porque razão é indeterminado o conteúdo da variável global Value?

d) Monte uma experiência que prove a afirmação da alínea c). (sugestão: utilize a chamada sistema sleep).

2. Identificação e resolução de problemas de exclusão mútua

a) Copie o ficheiro aula3-eg2.tgz para a sua área de trabalho e descomprima o seu conteúdo:

  tar -zxvf aula3-eg2.tgz

b) Estude, compile e execute a aplicação. Compreenda o resultado (slide).

c) Que valores são possíveis para a variával Value no final da execução? Qual é o problema? Monte uma experiência que prove esta afirmação.

d) Corrija o problema do exemplo anterior utilizando trincos (slide). Verifique que, com esta alteração, a experiência montada na alínea anterior produz um resultado correcto.

e) A solução funcionaria se a variável Mutex fosse local à função thr_func?

Material de Apoio

 


Exercícios

Tarefas Contadoras

Implemente uma aplicação que incrementa concorrentemente uma variável Counter de 0 até 20 utilizando tarefas. Pode utilizar como esqueleto base a estrutura aula3-eg3.tgz. Sugestão: crie versões individuais da solução de cada uma das alíneas.

1. Tarefas concorrentes

a) Utilize duas tarefas, implementadas por duas funções - thr_inc_even e thr_inc_odd. A primeira incrementa o valor se Counter for par, a outra se Counter for ímpar. Sincronize devidamente o acesso à variável partilhada com trincos. As tarefas devem imprimir uma mensagem cada vez que incrementarem a variável partilhada. Por exemplo, o resultado deve ser o seguinte:

        ...
        [E] Counter=11
        [O] Counter=12
        [E] Counter=13
        [O] Counter=14
        ...

b) Generalize o exercício anterior de forma que a variável seja incrementada por N tarefas (N é definido por uma constante). A cada tarefa é atribuída um identificador id (entre 0 e N-1). Cada tarefa só incrementa Counter quando id=Counter%N. Ao invés de E ou O, deve ser impresso a identificação da tarefa que incrementa a variável. Sugestão: utilize apenas uma função thr_incrementer que receba como argumento o identificador da função (exemplo).

i) Faça testes com diferentes valores de N.

ii) Faça experiências inserindo instruções de sleep na secção crítica para confirmar que a sincronização funciona devidamente.

iii) Porque razão se definiu a secção dessa forma? Porque não mais pequena ou maior?

c) Modifique a solução anterior utilizando um semáforo para substituir o trinco (exemplo).

i) Qual o significado do valor 1 na inicialização do semáforo?

ii) Se o valor de inicialização do semáforo fosse diferente de 1, teria um comportamento semelhante ao trinco?

2. Tarefas cooperantes

Utilize agora duas tarefas em cascata - thr_inc_low e thr_inc_high, respectivamente. A primeira incrementa Counter entre 0 e 10, a segunda incrementa Counter entre 11 e 20. Ambas são lançadas simultaneamente, mas a tarefa thr_inc_high deve ficar bloqueada até que a tarefa thr_inc_low termine. Utilize um semáforo para sincronizar as tarefas.

a) Com que valor deve inicializar o semáforo?

b) Qual a função que o semáforo desempenha em termos de sincronização?

c) Neste caso tem algum problema de exclusão mútua que necessita resolver? Porquê?

 


Exercício Suplementar

Produtores-Consumidores

Considere um buffer circular com capacidade para armazenar N itens de informação. O buffer é usado para transmitir informação dos processos produtores para os processos consumidores. Em cada acesso ao buffer, cada produtor deposita apenas um item no buffer e cada consumidor retira apenas um item. Quando um produtor tenta introduzir informação no buffer estando este repleto, deve passar ao estado bloqueado; o mesmo deve suceder a um consumidor que tenta extrair um item quando o buffer está vazio. Os processos assim bloqueados devem ser acordados apenas quando o conteúdo do buffer assim o justificar.

Utilize o esqueleto aula3-eg6.tgz como base para a implementação do exercício. Implemente as funções thr_producer e thr_consumer de forma a obedecer a especificação. Utilize semáforos e trincos para sincronização.


Exercício de Avaliação 3

Multiplas tarefas cooperantes

Estenda o exercício das tarefas cooperantes (exercício 2) de forma a usar 3 tarefas. Cada tarefa é responsável por incrementar a variável Counter quando esta se encontra numa determinada gama de valores. Por exemplo:

As 3 tarefas são lançadas simultaneamente.

Outros requisitos: