2. O sistema operativo é um dos principais componentes de qualquer sistema informática e oferece vários serviços, entre os quais:
- Gestão de recursos: o SO é responsável pela gestão de um conjunto de recursos lógicos que simplificam a utilização dos recursos físicos base;
 - Execução de programas: concede um ambiente para a execução dos programas;
 - Operações I/O: comunicação entre o utilizador do SO e os drivers dos dispositivos;
 - Proteção: isolamento dos espaços de endereçamento de cada processo.
 
3. Uma tarefa é um fluxo de execução que se executa no âmbito de um processo já existente, executando funções do programa associado ao processo. Por partilhar o espaço de endereçamento com o processo ao qual está associado, partilha de dados é mais rápida e a comutação é mais rápida (quando comparada à comutação entre processos).
As threads são especialmente úteis em ambientes onde se pretende uma elevado throughput na realização de tarefas. Um exemplo prático da sua utilização verifica-se nos servidores web, onde um processo servidor, ao receber um pedido, despoleta uma nova thread para tratar do pedido efetuado.
4.
a. Algoritmo de Bakery p/ 2 processos.
b.
p1() {
	while (1) {
		regiao-nao-critica();
		n1 = 1;
		n1 = n2+1;
		while(n2 && n1 > n2) {
			regiao-critica();
			n1 = 0;
		}
	}
}
p2() {
	while (1) {
		regiao-nao-critica();
		n2 = 1;
		n2 = n1+1;
		while(n1 && n2 >= n1) {
			regiao-critica();
			n2 = 0;
		}
	}
}p2 acederá primeiro à secção crítica verificar-se-á a condição de entrada no while (n1 = 1 e n2 >= 1, logo TRUE).
c. As soluções algorítmicas têm diversas desvantagens:
- Apenas contemplam espera ativa;
 - Os algoritmos são desenhados para uma situação onde existem apenas 2 processos:
- O algoritmo de Lamport, desenhado para contemplar a coordenadação de acesso a uma região crítica por N (arbitrário) rocessos, é complexo;
 
 
6.
a. Os items produzidos na linha 7 poderão não ser colocados em buf se dois processos executarem essa instrução em simultâneo.
b. Vários processos podem "consumir" o mesmo item se executarem a linha 5 em simultâneo.
c.
int buf[N];
int prodptr=0, consptr=0;
pthread_mutex_t prod_m, cons_m;
sem_t semCons = 0, semProd = 6;
produtor() {
	int item = produz();
	sem_wait(&semProd);
	pthread_mutex_lock(&prod_m);
	buf[prodptr] = item;
	prodptr = (prodptr+1) % N;
	pthread_mutex_unlock(&prod_m);
	sem_post(&semCons);
}
consumidor() {
	int item;
	sem_wait(&semCons);
	pthread_mutex_lock(&cons_m);
	item = buf[consptr];
	consptr = (consptr+1) % N;
	pthread_mutex_unlock(&cons_m);
	sem_post(&semProd);
	consome(item);
}