Skip to content

Instantly share code, notes, and snippets.

@senhorinha
Last active August 29, 2015 14:05
Show Gist options
  • Save senhorinha/571a38f6f892a605795f to your computer and use it in GitHub Desktop.
Save senhorinha/571a38f6f892a605795f to your computer and use it in GitHub Desktop.
Explicação das modificações para o primeiro trabalho S.O2

Semaphore

Em semaphore.h foi adicionado um atributos. O processosEmEspera como o nome diz, representa uma fila de processos que estão aguardando execução.-

private:
    volatile int _value;
    Queue<Thread> processosEmEspera;
};

Em p (decremento) é verificado se há processo em espera para ser executado. Se houver, o processo que pediu recurso ao semafaro é adicionado a lista de espera processosEmEspera.insert(&processo->e);. Caso o if if (_value > 0 && processosEmEspera.size() == 0) {} seja satisfeito o semafaro sofre decremento e o processo inicia a execução processo.join();. O valor de retorno de join representa o número de iterações da thread.

int Semaphore::p(Thread processo) {
	db<Synchronizer>(TRC) << "Semaphore::p(this=" << this << ",value=" << _value
			<< ")" << endl;
	int ret;
	if (_value > 0 && processosEmEspera.size() == 0) {
		_value -= 1;
		ret = processo.join();
	} else {
		processosEmEspera.insert_tail(&processo._link);
	}
	return ret;
}

Em v (incremento) é feito a verificação se o processo que pede a liberação de recurso está atualmente sendo executado. Isso evita que outros processos, em espera por exemplo, liberem inadvertidamente o recurso. Logo após a verificação, se o processo estiver em execução ele é removido da lista. Em seguida, se houver processos em espera processosEmEspera.size() > 0 o primeiro da lista de espera é retirado e pede ao chama p para entrar em execução.

void Semaphore::v(Thread processo) {
	db<Synchronizer>(TRC) << "Semaphore::v(this=" << this << ",value=" << _value
			<< ")" << endl;
	if (processo.state() == Thread::State::RUNNING) {
		_value += 1;
		if (processosEmEspera.size() > 0) {
			Thread processoParaExecutar = processosEmEspera.remove_head();
			p(processoParaExecutar);
		}
	}
}

Main

Na execução do main, para utilizar as novas estruturas, foi necessário refatora-lo. A primeira mudança foi a necessidade de criar um "preparador de jantar" que é uma Thread que realiza a tarefa de construir o jantar, ou seja, criar os filosofos e imprimir a mesa. Isso foi necessário pois, agora, nosso semáforo exige que seja passado em v e p uma thread, com isso, para o preparador conseguir bloquear a mesa era necessário que fosse uma thread. Segue o método para preparo da mesa:

int prepararJantar() {
	Display::clear();
	Display::position(0, 0);
	cout << "The Philosopher's Dinner:" << endl;

	for (int i = 0; i < 5; i++)
		chopstick[i] = new Semaphore;

	phil[0] = new Thread(&philosopher, 0, 5, 32);
	phil[1] = new Thread(&philosopher, 1, 10, 44);
	phil[2] = new Thread(&philosopher, 2, 16, 39);
	phil[3] = new Thread(&philosopher, 3, 16, 24);
	phil[4] = new Thread(&philosopher, 4, 10, 20);

	cout << "Philosophers are alive and hungry!" << endl;

	Display::position(7, 44);
	cout << '/';
	Display::position(13, 44);
	cout << '\\';
	Display::position(16, 35);
	cout << '|';
	Display::position(13, 27);
	cout << '/';
	Display::position(7, 27);
	cout << '\\';
	Display::position(19, 0);

	cout << "The dinner is served ..." << endl;
	return 1;
}

Depois que o jantar foi preparado, os filosofos começam a disputar por recursos. Segue o main resultante do processo de refatoração.

int main() {
	preparadorDoJantar = new Thread(&prepararJantar);
	table.p(preparadorDoJantar);
	table.v(preparadorDoJantar);

	for (int i = 0; i < 5; i++) {
		int ret = table.p(phil[i]);
		Display::position(20 + i, 0);
		cout << "Philosopher " << i << " ate " << ret << " times " << endl;
		table.v(phil[i]);
	}

	for (int i = 0; i < 5; i++)
		delete chopstick[i];
	for (int i = 0; i < 5; i++)
		delete phil[i];

	cout << "The end!" << endl;

	return 0;
}

Alguns problemas :)

O método int Semaphore::p(Thread processo) { } não está sabendo adicionar. O eclipse reclama que o tipo que está sendo passado não está correto. Segue a mensagem de erro:

'```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment