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.tgzb) 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.tgzb) 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çãothr_func
?
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
ethr_inc_odd
. A primeira incrementa o valor seCounter
for par, a outra seCounter
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ó incrementaCounter
quandoid=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çãothr_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ê?
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.
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:
Counter
quando Counter % 3 = 0
.Counter
quando Counter % 3 = 1
.Counter
quando Counter % 3 = 2
.As 3 tarefas são lançadas simultaneamente.
Outros requisitos:
thr_inc_module
que recebe como argumento uma estrutura com o módulo, o valor da thread, e o máximo.