Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
Ambos lados da revisão anterior Revisão anterior Próxima revisão | Revisão anterior | ||
so:exercicios_de_coordenacao [2023/05/12 18:26] – maziero | so:exercicios_de_coordenacao [2024/04/17 20:38] (atual) – [A granja de ovos] maziero | ||
---|---|---|---|
Linha 1: | Linha 1: | ||
+ | ====== Exercícios de coordenação ====== | ||
+ | Exercícios de coordenação usando //threads// Posix e semáforos (ou // | ||
+ | |||
+ | ==== Ordem estrita ==== | ||
+ | |||
+ | Considerando 5 //threads// lançadas simultaneamente com suas respectivas funções definidas abaixo, use semáforos para garantir que a saída na tela seja sempre '' | ||
+ | |||
+ | < | ||
+ | Task A Task E Task I Task O Task U | ||
+ | { | ||
+ | printf (" | ||
+ | task_exit () task_exit () task_exit () task_exit () task_exit () | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Robôs Simpsons ==== | ||
+ | |||
+ | Suponha três robôs (//Bart//, //Lisa//, // | ||
+ | |||
+ | < | ||
+ | Bart | ||
+ | Lisa | ||
+ | Maggie | ||
+ | Lisa | ||
+ | Bart | ||
+ | Lisa | ||
+ | Maggie | ||
+ | Lisa | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | Evite situações de espera ocupada (//busy wait//). | ||
+ | |||
+ | ==== Barreiras ==== | ||
+ | |||
+ | Uma [[https:// | ||
+ | |||
+ | O exemplo a seguir ilustra o uso de uma barreira: | ||
+ | |||
+ | < | ||
+ | barrier_init (&b, 3) ; // define uma barreira para 3 tarefas | ||
+ | |||
+ | Task A | ||
+ | { | ||
+ | printf ("A antes\n" | ||
+ | barrier_wait (&b) ; // espera na barreira | ||
+ | printf ("A depois\n" | ||
+ | } | ||
+ | | ||
+ | Task B | ||
+ | { | ||
+ | printf ("B antes\n" | ||
+ | barrier_wait (&b) ; // espera na barreira | ||
+ | printf ("B depois\n" | ||
+ | } | ||
+ | |||
+ | Task C | ||
+ | { | ||
+ | printf ("C antes\n" | ||
+ | barrier_wait (&b) ; // espera na barreira | ||
+ | printf ("C depois\n" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | A execução do código deve gerar uma saída na qual todas as operações " | ||
+ | |||
+ | < | ||
+ | A antes | ||
+ | C antes | ||
+ | B antes | ||
+ | -- (barreira) | ||
+ | C depois | ||
+ | B depois | ||
+ | A depois | ||
+ | </ | ||
+ | |||
+ | Implemente as operações '' | ||
+ | |||
+ | ==== Banheiro Unissex ==== | ||
+ | |||
+ | Este problema foi adaptado do [[http:// | ||
+ | |||
+ | Em um departamento de informática com apenas um banheiro disponível((esta é uma situação totalmente hipotética...)), | ||
+ | |||
+ | * Homens e mulheres não podem usar simultaneamente o banheiro. | ||
+ | * Não pode haver mais de 3 pessoas usando o banheiro ao mesmo tempo. | ||
+ | * Obviamente, não podem ocorrer impasses. | ||
+ | |||
+ | Usando //threads// e semáforos, escreva o código necessário para garantir essas restrições. As //threads// têm o seguinte comportamento (sem a parte de coordenação): | ||
+ | |||
+ | < | ||
+ | task homem | ||
+ | { | ||
+ | while (true) | ||
+ | { | ||
+ | trabalhar () ; | ||
+ | usar_banheiro_h () ; | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | task mulher | ||
+ | { | ||
+ | while (true) | ||
+ | { | ||
+ | trabalhar () ; | ||
+ | usar_banheiro_m () ; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Jantar dos selvagens ==== | ||
+ | |||
+ | Este problema foi adaptado do [[http:// | ||
+ | |||
+ | No jantar comunal de uma tribo remota, um cozinheiro serve ensopado em um caldeirão, que tem capacidade para //N// porções. Cada convidado se serve de uma porção de ensopado; caso o caldeirão fique vazio, o cozinheiro deve ser chamado para enchê-lo novamente, enquanto os convidados esperam para se servir. Enquanto não tiver o que fazer, o cozinheiro dorme. | ||
+ | |||
+ | Código do cozinheiro (sem a parte de coordenação): | ||
+ | |||
+ | < | ||
+ | task cozinheiro() | ||
+ | { | ||
+ | while (true) | ||
+ | enche_caldeirao(N) ; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Código dos convidados (idem): | ||
+ | |||
+ | < | ||
+ | task convidado() | ||
+ | { | ||
+ | while (true) | ||
+ | { | ||
+ | serve_porção() ; | ||
+ | come() ; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== A granja de ovos ==== | ||
+ | |||
+ | Em uma granja, 30 galinhas produzem ovos. Cada galinha bota um ou dois ovos por vez; todos os ovos produzidos pelas galinhas caem diretamente em uma cesta de ovos com capacidade infinita (nenhum ovo quebra). | ||
+ | |||
+ | Os ovos que caem na cesta são coletadas por 5 fazendeiros. Cada fazendeiro pega uma bandeja com capacidade para 6 ovos e espera. Quando houver ovos suficientes na cesta, o fazendeiro pega os ovos e enche sua bandeja; em seguida, pega uma nova bandeja vazia e recomeça o ciclo. | ||
+ | |||
+ | Modelando cada galinha e cada fazendeiro com sua própria //thread//, escreva o código de sincronização para NG galinhas, NF fazendeiros e bandejas com capacidade para NB ovos cada. | ||
+ | |||
+ | **Sugestão**: | ||
+ | |||
+ | Sugestão de pseudocódigo das galinhas e dos fazendeiros: | ||
+ | |||
+ | < | ||
+ | task galinha () | ||
+ | { | ||
+ | while (true) | ||
+ | { | ||
+ | // coloca um ou dois ovos na cesta | ||
+ | novos_ovos = 1 + random() % 2 ; | ||
+ | ovos_cesta += novos_ovos ; | ||
+ | |||
+ | // se há NB ou mais ovos na cesta, avisa um fazendeiro | ||
+ | if (ovos_cesta >= NB) | ||
+ | sinaliza condição | ||
+ | |||
+ | sleep (1) ; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | task fazendeiro () | ||
+ | { | ||
+ | while (true) | ||
+ | { | ||
+ | // se não houver ovos suficientes na cesta, espera | ||
+ | while (ovos_cesta < NB) | ||
+ | espera condição | ||
+ | |||
+ | // retira NB ovos da cesta | ||
+ | ovos_cesta -= NB ; | ||
+ | |||
+ | sleep (1) | ||
+ | } | ||
+ | } | ||
+ | </ |