Added exercices in portuguese

This commit is contained in:
Rui Ribeiro 2025-10-07 12:20:55 +01:00
parent 7365014c96
commit 0a91d2dabd
14 changed files with 325 additions and 2 deletions

22
10_philosophers_args.txt Normal file
View File

@ -0,0 +1,22 @@
Assignment name: philosophers_args
Expected files: philosophers_args.c
Allowed functions: memset, printf, malloc, free, write, pthread_create,
pthread_detach, pthread_join, pthread_mutex_init, pthread_mutex_destroy,
pthread_mutex_lock, pthread_mutex_unlock, usleep, gettimeofday
------------------------------------------------------------------------
Implementa o problema completo dos filósofos com parsing de argumentos:
Argumentos: `number_of_philosophers time_to_die time_to_eat time_to_sleep [number_of_times_must_eat]`
Comportamento:
- Cada filósofo alterna: pensar → tentar pegar forks → comer → largar forks → dormir
- Se um filósofo não comer dentro de `time_to_die`, morre e programa termina
- Se `number_of_times_must_eat` especificado, programa termina quando todos comeram esse número de vezes
- Thread monitor verifica mortes a cada 1ms
Uso: `./philosophers_args 5 800 200 200` ou `./philosophers_args 5 800 200 200 7`
Hint: Este é praticamente o projeto Philosophers completo.
Implementa parsing robusto de argumentos, validação de inputs, e cleanup adequado de recursos.
A thread monitor é crítica - deve detectar morte rapidamente sem afetar performance.

24
11_race_detector.txt Normal file
View File

@ -0,0 +1,24 @@
Assignment name: race_detector
Expected files: race_detector.c
Allowed functions: memset, printf, malloc, free, write, pthread_create, pthread_detach,
pthread_join, pthread_mutex_init, pthread_mutex_destroy,
pthread_mutex_lock, pthread_mutex_unlock, usleep, gettimeofday
----------------------------------------------------------------------------------------
Cria uma versão do problema dos filósofos que:
1. Detecta e reporta possíveis data races
2. Testa diferentes estratégias de otimização:
- Estratégia A: mutex global para todas as operações
- Estratégia B: mutex por fork + mutex para impressão
- Estratégia C: minimizar lock time
Inclui stress test: roda 100 iterações com diferentes configurações e reporta:
- Número de data races detectadas
- Performance (tempo total)
- Número de mortes
Uso: `./race_detector 4 410 200 200`
Hint: Use ferramentas como `valgrind --tool=helgrind` para detectar data races.
No projeto real, qualquer data race resulta em nota 0.
Testa com números ímpares e pares de filósofos, e com time_to_die muito próximo de time_to_eat.

24
12_philosophers_bonus.txt Normal file
View File

@ -0,0 +1,24 @@
Assignment name: philosophers_bonus
Expected files: philosophers_bonus.c
Allowed functions: memset, printf, malloc, free, write, fork, kill, exit,
pthread_create, pthread_detach, pthread_join, usleep, gettimeofday,
waitpid, sem_open, sem_close, sem_post, sem_wait, sem_unlink
-------------------------------------------------------------------------
Implementa a versão bonus do Philosophers:
- Cada filósofo é um processo separado (não thread)
- Usa semáforos POSIX nomeados para coordenação
- Processo pai monitora todos os processos filhos
- Se um filósofo morre, mata todos os outros processos
Funcionalidades adicionais:
- Cleanup adequado de semáforos nomeados
- Handling de sinais (SIGINT, SIGTERM)
- Relatório final com estatísticas
Uso: `./philosophers_bonus 5 800 200 200 7`
Hint: Bonus part usa processos em vez de threads.
Semáforos POSIX nomeados permitem comunicação entre processos.
Usa fork() para criar processos filhos e waitpid() para monitorizar.
O cleanup de semáforos é crucial - usa sem_unlink() e handling de sinais para cleanup em caso de interrupção.

19
1_thread_basics.txt Normal file
View File

@ -0,0 +1,19 @@
Assignment name: thread_basics
Expected files: thread_basics.c
Allowed functions: memset, printf, malloc, free, write, pthread_create,
pthread_detach, pthread_join, usleep, gettimeofday
-------------------------------------------------------------------------------
Cria um programa que lance 2 threads. Cada thread deve imprimir o seu ID e uma mensagem diferente.
O programa principal deve esperar que ambas as threads terminem antes de sair.
Thread 1 deve imprimir: "Thread 1: Hello from thread 1"
Thread 2 deve imprimir: "Thread 2: Hello from thread 2"
O programa deve aceitar como argumento o número de mensagens que cada thread deve imprimir.
Uso: `./thread_basics 5`
Hint: Este exercício ensina-te a base de pthread_create e pthread_join.
Lembra-te de verificar os valores de retorno das funções pthread.
Usa uma estrutura para passar argumentos às threads.

18
2_mutex_basics.txt Normal file
View File

@ -0,0 +1,18 @@
Assignment name: mutex_basics
Expected files: mutex_basics.c
Allowed functions: memset, printf, malloc, free, write, pthread_create, pthread_detach
pthread_join, pthread_mutex_init, pthread_mutex_destroy
pthread_mutex_lock, pthread_mutex_unlock, usleep, gettimeofday
--------------------------------------------------------------------------------------
Cria um programa com uma variável global `counter` inicializada a 0.
Lança 4 threads que incrementam esta variável 1000 vezes cada uma.
Usa um mutex para proteger o acesso à variável.
O programa deve imprimir o valor final de `counter` (deve ser 4000) e o tempo total de execução.
Uso: `./mutex_basics`
Hint: Sem mutex, vais ver valores incorretos devido a race conditions.
O mutex garante que apenas uma thread acede à variável de cada vez.
Este é o conceito fundamental para o projeto Philosophers.

23
3_precise_timing.txt Normal file
View File

@ -0,0 +1,23 @@
Assignment name: precise_timing
Expected files: precise_timing.c
Allowed functions: memset, printf, malloc, free, write, pthread_create, pthread_detach,
pthread_join, pthread_mutex_init, pthread_mutex_destroy,
pthread_mutex_lock, pthread_mutex_unlock, usleep, gettimeofday
---------------------------------------------------------------------------------------
Implementa as seguintes funções:
- `long long get_current_time()` - retorna o tempo atual em milissegundos
- `void precise_sleep(int ms)` - dorme por exatamente X milissegundos
- `long long time_diff(long long start, long long end)` - calcula diferença entre tempos
Cria um programa que testa estas funções:
1. Mede o tempo de início
2. Dorme por 100ms usando precise_sleep
3. Mede o tempo de fim
4. Imprime a diferença (deve ser ~100ms)
Uso: `./precise_timing`
Hint: gettimeofday() é crucial no projeto Philosophers.
usleep() não é sempre preciso, por isso tens de verificar o tempo periodicamente.
No Philosophers, o timing preciso é essencial para detectar mortes.

23
4_state_monitor.txt Normal file
View File

@ -0,0 +1,23 @@
**Assignment name**: state_monitor
**Expected files**: state_monitor.c
**Allowed functions**: memset, printf, malloc, free, write, pthread_create,
pthread_detach, pthread_join, pthread_mutex_init, pthread_mutex_destroy,
pthread_mutex_lock, pthread_mutex_unlock, usleep, gettimeofday
---------------------------------------------------------------------------
Cria um programa com 3 threads "worker" e 1 thread "monitor":
**Worker threads**: Cada thread alterna entre 3 estados:
- WORKING (2 segundos)
- RESTING (1 segundo)
- THINKING (1.5 segundos)
Cada mudança de estado deve ser impressa com timestamp: `[timestamp] Worker X is WORKING`
**Monitor thread**: Verifica se algum worker está no mesmo estado há mais de 3 segundos.
Se sim, imprime: `[timestamp] WARNING: Worker X stuck in STATE`
**Uso**: `./state_monitor`
**Hint**: Use enums para os estados. O monitor thread simula a verificação de morte no Philosophers,
tens de verificar continuamente sem interferir com os workers. Usa mutex para proteger o acesso aos estados.

23
5_producer_consumer.txt Normal file
View File

@ -0,0 +1,23 @@
Assignment name: producer_consumer
Expected files: producer_consumer.c
Allowed functions: memset, printf, malloc, free, write, pthread_create,
pthread_detach, pthread_join, pthread_mutex_init, pthread_mutex_destroy,
pthread_mutex_lock, pthread_mutex_unlock, usleep, gettimeofday
---------------------------------------------------------------------------
Implementa o problema clássico Producer-Consumer:
- 2 threads Producer: produzem items (números de 1 a 100) e colocam num buffer
- 2 threads Consumer: consomem items do buffer e processam-nos
- Buffer partilhado com capacidade limitada (10 items)
Regras:
- Producers devem esperar se buffer estiver cheio
- Consumers devem esperar se buffer estiver vazio
- Não deve haver race conditions
- Imprime quando items são produzidos/consumidos
Uso: `./producer_consumer`
Hint: Este exercício ensina-te a coordenação entre múltiplas threads com recursos limitados.
É similar ao problema dos forks no Philosophers.
Usa mutexes para proteger o buffer e condition variables ou sleep para coordenação.

24
6_deadlock_demo.txt Normal file
View File

@ -0,0 +1,24 @@
Assignment name: deadlock_demo
Expected files: deadlock_demo.c
Allowed functions: memset, printf, malloc, free, write, pthread_create, pthread_detach,
pthread_join, pthread_mutex_init, pthread_mutex_destroy, pthread_mutex_lock,
pthread_mutex_unlock, usleep, gettimeofday
---
Cria um programa que demonstra deadlock e depois mostra como o resolver:
Parte 1 - Deadlock:
2 threads, 2 mutexes (mutex_a, mutex_b)
- Thread 1: lock mutex_a → sleep 100ms → lock mutex_b → unlock ambos
- Thread 2: lock mutex_b → sleep 100ms → lock mutex_a → unlock ambos
Parte 2 - Solução: Ambas threads fazem lock dos mutexes na mesma ordem.
O programa deve aceitar um argumento: 0 para deadlock, 1 para solução.
Uso: `./deadlock_demo 0` (demonstra deadlock)
Uso: `./deadlock_demo 1` (demonstra solução)
Hint: Deadlock é um risco real no Philosophers quando filósofos tentam pegar forks em ordens diferentes.
A solução mais comum é ordenar os recursos (forks com IDs mais baixos primeiro).

23
7_limited_resources.txt Normal file
View File

@ -0,0 +1,23 @@
**Assignment name**: limited_resources
**Expected files**: limited_resources.c
**Allowed functions**: memset, printf, malloc, free, write, pthread_create, pthread_detach,
pthread_join, pthread_mutex_init, pthread_mutex_destroy, pthread_mutex_lock, pthread_mutex_unlock, usleep, gettimeofday
---
Simula uma biblioteca com 3 computadores partilhados entre 10 estudantes:
- Cada estudante (thread) quer usar um computador por 2-5 segundos (tempo aleatório)
- Apenas 3 estudantes podem usar computadores simultaneamente
- Implementa um "semáforo" usando mutexes e uma variável contador
Imprime quando estudantes:
- Chegam à biblioteca
- Conseguem um computador
- Terminam de usar o computador
- Saem da biblioteca
**Uso**: `./limited_resources`
**Hint**: Como POSIX semáforos não são permitidos no mandatory part,
implementa o teu próprio semáforo com mutex + contador + condition logic.
Este exercício simula a limitação de recursos como no Philosophers com forks.

19
8_simple_philosophers.txt Normal file
View File

@ -0,0 +1,19 @@
Assignment name: simple_philosophers
Expected files: simple_philosophers.c
Allowed functions: memset, printf, malloc, free, write, pthread_create, pthread_detach,
pthread_join, pthread_mutex_init, pthread_mutex_destroy, pthread_mutex_lock, pthread_mutex_unlock, usleep, gettimeofday
---
Implementa uma versão simplificada do problema dos filósofos:
- 3 filósofos sentados numa mesa circular
- 3 forks (um entre cada par de filósofos)
- Cada filósofo alterna entre: pensar (1s) → pegar forks → comer (1s) → largar forks → repetir
- Programa corre por 10 segundos e depois pára
Cada ação deve ser impressa: `[timestamp] Philosopher X is thinking/eating`
Uso: `./simple_philosophers`
Hint: Este é o núcleo do projeto Philosophers. Cada fork é protegido por um mutex.
Para evitar deadlock, implementa uma ordem consistente para pegar forks (fork com ID menor primeiro).
Usa uma thread monitor para parar após 10s.

21
9_death_monitor.txt Normal file
View File

@ -0,0 +1,21 @@
Assignment name: death_monitor
Expected files: death_monitor.c
Allowed functions: memset, printf, malloc, free, write, pthread_create, pthread_detach,
pthread_join, pthread_mutex_init, pthread_mutex_destroy, pthread_mutex_lock,
pthread_mutex_unlock, usleep, gettimeofday
---
Cria um sistema com:
- 4 threads "worker" que fazem trabalho por períodos variados (1-4 segundos)
- 1 thread monitor que verifica se algum worker não dá "sinal de vida" há mais de 3 segundos
- Workers devem atualizar `last_activity_time` a cada iteração
- Monitor verifica a cada 100ms e imprime aviso se detectar worker "morto"
Simula "morte" fazendo um worker parar aleatoriamente.
Uso: `./death_monitor`
Hint: Este exercício simula a detecção de morte no Philosophers.
O monitor thread deve verificar continuamente sem bloquear os workers.
Usa mutex para proteger `last_activity_time`.
A detecção deve ser rápida (dentro de 10ms no projeto real).

View File

@ -219,7 +219,7 @@ If you develop a new program, and you want it to be of the greatest possible use
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
philosophers_training
philosophers_prep
Copyright (C) 2025 ruiferna
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

View File

@ -1,2 +1,62 @@
# philosophers_training
# Exercícios Preparatórios — Projeto Philosophers
Bem-vindo ao repositório de exercícios práticos desenhados para construir, passo a passo, todos os conceitos necessários para dominar o projeto Philosophers da 42. Aqui vais encontrar desafios progressivos sobre threads, mutexes, deadlocks, sincronização, semáforos, timing, e muito mais em C.
## Objetivo
A proposta deste repositório é guiar estudantes pela aprendizagem real de programação concorrente, partindo do absoluto básico até à implementação de sistemas completos e robustos capazes de resolver o clássico problema dos Filósofos, incluindo as regras e desafios da bonus part.
## Estrutura dos Exercícios
Cada exercício segue uma estrutura clara e normalizada, incluindo:
- **Assignment name**
- **Expected files**
- **Allowed functions**
- **Descrição do problema**
- **Sugestão/Hint para a resolução**
### Lista de Exercícios
| Nº | Nome | Conteúdo-chave |
|----|---------------------------|---------------------------------------------|
| 1 | thread_basics | Threads, pthread_create, pthread_join |
| 2 | mutex_basics | Mutexes, race conditions |
| 3 | precise_timing | gettimeofday, usleep, timing |
| 4 | state_monitor | Monitorização, enums, padrões monitor |
| 5 | producer_consumer | Sincronização, coordination problems |
| 6 | deadlock_demo | Deadlock, prevenção de deadlock |
| 7 | limited_resources | Semáforo manual, acesso limitado |
| 8 | simple_philosophers | Problema dos filósofos simplificado |
| 9 | death_monitor | Monitorização de vida, threads watchdog |
| 10 | philosophers_args | Implementação 'full', argumentos |
| 11 | race_detector | Data races, otimização de locks |
| 12 | philosophers_bonus | Processos, semáforos POSIX, bonus part |
## Como usar
1. **Cada exercício é independente.** Recomenda-se seguir pela ordem, para garantir a aprendizagem progressiva.
2. **Compilar cada exercício:**
```sh
gcc -Wall -Wextra -Werror -pthread <nome_ficheiro>.c -o <programa>
```
3. **Executar cada binário** seguindo as instruções e exemplos do cabeçalho do exercício.
## Requisitos Técnicos
- Compilador C (ex: gcc)
- Ambiente POSIX (Linux ou Mac OS X recomendado)
- Bibliotecas pthreads standard
## Recomendações
- Não uses funções externas às permitidas.
- Lê atentamente os hints fornecidos para cada exercício.
- Analisa erros de race condition e deadlocks usando ferramentas como `valgrind --tool=helgrind`.
- Consulta [The Little Book of Semaphores](https://greenteapress.com/wp/semaphores/) para cimentar conceitos.
## Créditos e Referências
- Inspirado no livro open-source **The Little Book of Semaphores** por Allen B. Downey.
- Estrutura e avaliação baseadas no formato dos projetos 42.
- Problema clássico dos Filósofos por Edsger W. Dijkstra.