Sema Faro

32
FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO 1. INTRODUÇÃO Uma Thread (Linha ou Escalonamento de execução) é uma forma de um processo que dividir a si mesmo em duas mais tarefas que podem ser executadas concorrentemente. Possibilitando implementar aplicações concorrente com uma maior eficiência. Uma thread permite, por exemplo, que o usuário de um programa utilize uma funcionalidade do ambiente enquanto outras linhas de execução realizam outros cálculos e operações. Com isso temos possibilidade de implementa um processo de várias formas, uma delas e a possibilidade de interlaçar dois ou mais programas, sendo que ao executar certos trechos críticos, pode-se ter alguns comportamentos instável sendo que seus resultados dependem integralmente de uma ordem de execução, que na visão de um programados isso não pode ocorrer. Para sarnarmos isso deve-se usar uma técnica em programação concorrente para evitar que dois processos ou Threads tenham acesso simultaneamente a um recurso compartilhado (acesso esse denominado secção crítica) que é a Exclusão Mútua. Muitos métodos forma usados para garantir a exclusão mútua, mas em 1968 Dijkstra criou o conceito de Semáforos, e também sendo capazes de resolver uma grande variedades de problemas. O Semáforo é um objeto com apenas um membro de dados representados por um inteiro sem sinal e dois métodos que definem às únicas operações permitidas: WAIT(S), se é um positivo, decrementa o valor de S. se S e igual a zero, suspende a thread no semáforo. SIGNAL(S), acorda uma Thread que esteja suspensa no semáforo. Caso não haja nenhuma, incrementa o valor de S. Com isso é possível satisfazer as quatro propriedades básicas para a implementação de programação concorrente utilizando threads: Exclusão mútua, ausência de deadlock, ausência de inanição e chegada na ausência de contenção. 2. OBJETIVOS Montar o Algoritmo do problema e em seguida implementá-lo. Deve-se imprimir mensagens mostrando o que está acontecendo no programa implementado 3. FERRAMENTAS UTILIZADAS Computador com o Software Dev-C++.

Transcript of Sema Faro

Page 1: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

1. INTRODUÇÃO

Uma Thread (Linha ou Escalonamento de execução) é uma forma de um processo que

dividir a si mesmo em duas mais tarefas que podem ser executadas concorrentemente.

Possibilitando implementar aplicações concorrente com uma maior eficiência. Uma

thread permite, por exemplo, que o usuário de um programa utilize uma funcionalidade

do ambiente enquanto outras linhas de execução realizam outros cálculos e operações.

Com isso temos possibilidade de implementa um processo de várias formas, uma delas e

a possibilidade de interlaçar dois ou mais programas, sendo que ao executar certos trechos

críticos, pode-se ter alguns comportamentos instável sendo que seus resultados dependem

integralmente de uma ordem de execução, que na visão de um programados isso não pode

ocorrer. Para sarnarmos isso deve-se usar uma técnica em programação concorrente para

evitar que dois processos ou Threads tenham acesso simultaneamente a um recurso

compartilhado (acesso esse denominado secção crítica) que é a Exclusão Mútua.

Muitos métodos forma usados para garantir a exclusão mútua, mas em 1968 Dijkstra criou

o conceito de Semáforos, e também sendo capazes de resolver uma grande variedades de

problemas.

O Semáforo é um objeto com apenas um membro de dados representados por um inteiro

sem sinal e dois métodos que definem às únicas operações permitidas: WAIT(S), se é um

positivo, decrementa o valor de S. se S e igual a zero, suspende a thread no semáforo.

SIGNAL(S), acorda uma Thread que esteja suspensa no semáforo. Caso não haja

nenhuma, incrementa o valor de S. Com isso é possível satisfazer as quatro propriedades

básicas para a implementação de programação concorrente utilizando threads: Exclusão

mútua, ausência de deadlock, ausência de inanição e chegada na ausência de contenção.

2. OBJETIVOS

• Montar o Algoritmo do problema e em seguida implementá-lo. Deve-se imprimir

mensagens mostrando o que está acontecendo no programa implementado

3. FERRAMENTAS UTILIZADAS

Computador com o Software Dev-C++.

Page 2: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

4. DESENVOLVIMENTO

Conforme solicitado, foram implementados os seguintes problemas:

1. Produtor e Consumidor,

2. Filósofos,

3. Salão de Barbeiro,

4. Fumantes,

5. Jantar dos Selvagens,

6. Montanha Russa,

7. Filme e

8. Pombo Correio.

Todos os programas a seguir foram implantados e suas execuções testadas, e seu

funcionamento foi todo comentado no próprio código e redigido no corpo deste trabalho.

4.1 Produtor e Consumidor

Neste programa foi implementado conforme implementação abaixo com seus

comentários inseridos. Sendo que para alteração do Buffer para poder de ir de 10 a 24

posições de armazenamento, basta alterar o valor de N. Analisando a o algoritmo pode se

provar as propriedades, sendo que o produtor não pode inserir dados em um buffer cheio,

o consumidor não pode consumir dados no buffer, ausência de deadlock e não ocorre

inanição de nenhum processo.

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#include <process.h> // _beginthreadex() e _endthreadex()

#include <conio.h> // _getch

#include <string.h>

#define _CHECKERROR 1 // Ativa função CheckForError

#include "CheckForError.h"

// Casting para terceiro e sexto parâmetros da função _beginthreadex

typedef unsigned (WINAPI *CAST_FUNCTION)(LPVOID);

typedef unsigned *CAST_LPDWORD;

#define N 5

#define prod 5 //DEFINE O NUMERO DE PRODUTORES

#define cons 5 //DEFINE OS NUMEROS DE CONSUMIDORES

//DEFINE VALORES PARA FACILITAR

#define Produzir 0

#define Consumir 1

//DECARAÇÃO DOS SEMAFAROS

HANDLE VAZIOS;

HANDLE CHEIOS;

Page 3: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

// DECLARAÇÃO DAS FUNÇÕES

DWORD WINAPI Produtor(LPVOID);

DWORD WINAPI Consumidor(LPVOID);

int Buffer[N]; // Buffer circular

int InIndex = 0; // Índice para posição livre para inserção de dados

int OutIndex = 0; // Índice para posição ocupada contendo dado

int cont=0;

int main(){

int i;

//DECLARA AS THREADS

HANDLE PThreads[prod];

HANDLE CThreads[cons];

DWORD dwThreadIdcons, dwTheadIdprod;

DWORD dwExitCodecons = 0, dwExitCodeprod = 0;

DWORD dwRetcons, dwRetprod;

//CRIA SEMAFAROS

VAZIOS = CreateSemaphore(NULL,N,N,"VAZIO");

CHEIOS = CreateSemaphore(NULL,0,N,"CHEIO");

//CRIA THREADS PRODUTORES

for (i=0; i<prod; ++i) {

PThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)Produtor, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwTheadIdprod // cating necessário

);

if (PThreads[i]) printf("Produtor %d criada Id= %0x \n", i, dwTheadIdprod);

}

//CRIA THREADS CONSUMIDOR

for (i=0;i<cons; ++i){

CThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION) Consumidor, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwThreadIdcons // cating necessário

Page 4: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

);

if (CThreads[i]) printf("Consumidor %d criada Id= %0x \n", i, dwThreadIdcons);

}

dwRetprod = WaitForMultipleObjects(prod, PThreads,TRUE,INFINITE);

CheckForError((dwRetprod >= WAIT_OBJECT_0) && (dwRetprod < WAIT_OBJECT_0 +

prod));

dwRetcons = WaitForMultipleObjects(cons, CThreads,TRUE,INFINITE);

CheckForError((dwRetcons >= WAIT_OBJECT_0) && (dwRetcons < WAIT_OBJECT_0 +

cons));

//APAGA REFERENCIA DE THREADS

for (i=0; i<prod; ++i){

GetExitCodeThread(PThreads[i], &dwExitCodeprod);

CloseHandle(PThreads[i]); // apaga referência ao objeto

} // for

for (i=0; i<cons; ++i){

GetExitCodeThread(CThreads[i], &dwExitCodecons);

CloseHandle(CThreads[i]); // apaga referência ao objeto

} // for

//APAGA REFERENCIA DOS SEMAFAROS

CloseHandle(CHEIOS);

CloseHandle(VAZIOS);

printf("\nAcione uma tecla para terminar\n");

_getch(); // // Pare aqui, caso não esteja executando no ambiente MDS

return EXIT_SUCCESS;

} // main

DWORD WINAPI Produtor(LPVOID i){

LONG lOldValue;

Sleep(1000); // da um tempo para criar todo mundo e aumentar a concorrência

do{

Sleep(1000);

//ESPERA QUE HAJA ESPAÇO LIVRE

WaitForSingleObject(VAZIOS, INFINITE);

Sleep(100);

//INSERE DADO NO BUFFER

Page 5: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

Buffer[InIndex] = Produzir;

cont++;

printf("O Produtor %d Produziu!\n", cont);

// Aponta próxima posição livre

InIndex = (InIndex + 1)%N;

//SINALIZA CHEIO

ReleaseSemaphore(CHEIOS, 1, &lOldValue);

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc

DWORD WINAPI Consumidor(LPVOID i){

LONG lOldValue;

Sleep(1000); // da um tempo para criar todo mundo e aumentar a concorrência

do{

Sleep(1000);

//ESPERA QUE HAJA DADO PARA SER CONSUMIDO

WaitForSingleObject(CHEIOS, INFINITE);

Sleep(1000);

// Insere dado no buffer

Buffer[OutIndex] = Consumir;

printf("O Consumidor %d Consumiu!\n", cont);

cont--;

//APONTA PARA PROXIMA POSIÇÃO OCUPADA

OutIndex = (OutIndex + 1)%N;

//SINALIZA VAZIO

ReleaseSemaphore(VAZIOS, 1, &lOldValue);

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc.

4.2.Filósofos

Um dos problema clássicos mais famosos da história da computação. Cinco filósofos

estão sentados em torno de uma mesa circular, que tem em seu centro um prato

inesgotável de sushis (na história original era spaghetti, mas você precisa de um único

talher para comer spaghetti ou de dois talheres diferentes: um garfo e uma colher). Sobre

a mesa, entre cada dois filósofos está um talher japonês (hashi). Cada filósofo para comer

deve pegar dois talheres, uma vez que é difícil equilibrar um sushi em um único talher.

Cada filósofo realiza um loop infinito em que pensa, toma os talheres um a um, come e

devolve os talheres à mesa. As regrasa serem obedecidas são:

Page 6: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

P1: Dois filósofos não podem segurar um mesmo talher simultaneamente.

P2: O filósofo só come, quando tem dois talheres

P3: Não deve haver deadlock, situação em que nenhum dos filósofos consegue comer.

P4: Não pode haver inanição (neste caso inanição propriamente dita), isto é, um filósofo

querendo comer, deve eventualmente ter acesso aos dois talheres.

Eventualmente aqui significa: o evento (comer) ocorre com certeza, em algum instante

no futuro.

Conforme o enunciado foi implementado o algoritmo que se segue, com os comentários do

programa.

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#include <process.h> // _beginthreadex() e _endthreadex()

#include <conio.h> // _getch

#define _CHECKERROR 1 // Ativa função CheckForError

#include "CheckForError.h"

// Casting para terceiro e sexto parâmetros da função _beginthreadex

typedef unsigned (WINAPI *CAST_FUNCTION)(LPVOID);

typedef unsigned *CAST_LPDWORD;

#define N 5 //DEFINE A QUANTIDADE DE FILOSOFO

#define ESQUERDA (j + N -1)%N //DEFINE A ESQUERDA DE UM FILOSOFO

#define DIREITA (j+1)%N //DEFINE A DIREITA DO FILOSOFO

//ENUMERAÇÃO DOS ESTADOS

#define PENSANDO 0

#define COM_FOME 1

#define COMENDO 2

int Estado[N]; //BUFFER DOS ESTADOS

//DECLAÇÃO DOS SEMAFAROS

HANDLE MUTEX;

HANDLE S[N];

//FUNÇÕES DE TESTES E MOSTRA

void Pega_talheres(int);

void Devolve_talheres(int);

void Test(int);

void Mostrar(void);

DWORD WINAPI Filosofo(int); // declaração da função

int main()

Page 7: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

{

HANDLE hThreads[N]; //DECLARAÇÃO DA THREAD

int p;

DWORD dwThreadId;

DWORD dwExitCode = 0;

DWORD dwRet;

char filosofo;

//CRIAÇÃO DO MUTEX

MUTEX = CreateMutex(NULL, FALSE, "filosofo");

CheckForError(MUTEX);

//CRIAÇÃO SEMAFARO

for (p=0; p<N; ++p){

S[p] = CreateSemaphore(NULL,N,1,"filosofos");

}

//CRIAÇÃO DAS THREADS

for (p=0; p<N; ++p){

hThreads[p] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)Filosofo, // casting necessário

(LPVOID)p,

0,

(CAST_LPDWORD)&dwThreadId // casting necessário

);

if (hThreads[p]) printf("Filosofo %d Id= %0x \n", p, dwThreadId);

} // for

// Espera todas as threads terminarem

dwRet = WaitForMultipleObjects(N,hThreads,TRUE,INFINITE);

CheckForError((dwRet >= WAIT_OBJECT_0) && (dwRet < WAIT_OBJECT_0 + N));

for (p=0; p<N; ++p) {

dwRet=GetExitCodeThread(hThreads[p], &dwExitCode);

CheckForError(dwRet);

CloseHandle(hThreads[p]); // apaga referência ao objeto

} // for

//APAGA O MUTEX

CloseHandle(MUTEX);

//APAGA OS SEMAFAROS

Page 8: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

for (p=0; p<N; ++p){

CloseHandle(S[p]);

}

printf("\nAcione uma tecla para terminar\n");

_getch(); // // Pare aqui, caso não esteja executando no ambiente MDS

return EXIT_SUCCESS;

} // main

DWORD WINAPI Filosofo(int j){

do{

Sleep(5000); // da um tempo para criar todo mundo e aumentar a concorrência

Pega_talheres(j); // Pega ambos os talheres

Devolve_talheres(j);// Devolve talheres

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc

void Pega_talheres(int j){

WaitForSingleObject(MUTEX, INFINITE);// Anuncia que quer comer

Estado[j] = COM_FOME;

Mostrar();

Test(j); //Pede Talheres

ReleaseMutex(MUTEX);

WaitForSingleObject(S[j], INFINITE); // Fica a espera de talheres livres

}

void Devolve_talheres(int j){

WaitForSingleObject(MUTEX, INFINITE);

Estado[j] = PENSANDO; //Define um novo Estado

Mostrar();

Test(ESQUERDA); // Verifica se mudou estado do filósofo à esquerda

Test(DIREITA); // Verifica se mudou estado do filósofo à direita

ReleaseMutex(MUTEX);

}

void Test(int j) {

LONG lOldValue;

if ((Estado[j] == COM_FOME) && (Estado[ESQUERDA] != COMENDO) &&

(Estado[DIREITA]!=COMENDO))

{

Page 9: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

Estado[j]=COMENDO;

Mostrar();

ReleaseSemaphore(S[j], 1, &lOldValue); // Se o filósofo tem os dois talheres disponíveis,

acorde-o

}

}

void Mostrar(){

int i;

for(i=1; i<=N; i++){

if(Estado[i-1] == PENSANDO){

printf("O filosofo %d esta pensando!\n", i);

}

if(Estado[i-1] == COM_FOME){

printf("O filosofo %d esta com fome!\n", i);

}

if(Estado[i-1] == COMENDO){

printf("O filosofo %d esta comendo!\n", i);

}

}

printf("\n");

}

4.3.Salão de Barbeiro

Um salão de barbeiro tem uma cadeira de barbear, 5 cadeiras de espera, e um barbeiro.

Quando não há clientes, o barbeiro se senta na cadeira de barbear e dorme. Um cliente

chegando nesta situação é prontamente atendido. Se o cliente chega e o barbeiro está

ocupado, o cliente verifica o número de cadeiras de espera livres. Se existir alguma livre,

o cliente se senta e espera, caso contrário, vai embora. Gerencie o salão de barbeiro

usando semáforos.

Segue o algoritmo

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#include <process.h> // _beginthreadex() e _endthreadex()

#include <conio.h> // _getch

#define _CHECKERROR 1 // Ativa função CheckForError

#include "CheckForError.h"

Page 10: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

// Casting para terceiro e sexto parâmetros da função _beginthreadex

typedef unsigned (WINAPI *CAST_FUNCTION)(LPVOID);

typedef unsigned *CAST_LPDWORD;

#define NCADEIRAS 5 //DEFINE A QUANTIDADE DE CADEIRAS DE ESPERA

#define NCLIENTES 10 //DEFINE A QUANTIDADE DE CLIENTES QUE ENTRAM NO SALÃO

#define NBARBEIRO 1 // DEFINE O NUMERO DE BARBEIRO

HANDLE SBARBEIROS; //SEMAFARO DE BARBEIROS

HANDLE SCLIENTES; //SEMAFARO CONTROLA ENTRADA DOS CLIENTES NA CADEIRA DE

ESPERA

HANDLE SMUTEX; //SEMAFARO PARA SENTA NA CADEIRA DO BARBEIRO

HANDLE LMUTEX; //SEMAFARO PARA LEVANTAR DA CADEIRA DO BARBEIRO

int ESTADO=0, SENTADO=0, j=0;

DWORD WINAPI cliente(LPVOID); // DECLARAÇÃO DA FUNÇÃO CLIENTE

DWORD WINAPI barbeiro(LPVOID); // DECLARAÇÃO DA FUNÇÃO BARBEIRO

int main()

{

HANDLE BThreads[NBARBEIRO]; //THEADS BARBEIRO

HANDLE CThreads[NCLIENTES]; //THEADS CLIENTES

int i;

DWORD dwThreadIdcons, dwTheadIdprod;

DWORD dwExitCodecons = 0, dwExitCodeprod = 0;

DWORD dwRetcons, dwRetprod;

//CRIAÇÃO DOS SEMAFAROS

SMUTEX = CreateSemaphore(NULL,1,1,"MUTEX");

LMUTEX = CreateSemaphore(NULL,0,1,"MUTEX");

SCLIENTES = CreateSemaphore(NULL,1,1,"CLIENTES");

SBARBEIROS = CreateSemaphore(NULL,0,1,"BARBEIRO");

//CRIAÇÃO DA THREADS DO BARBEIRO

for (i=0; i<NBARBEIRO; ++i) {

BThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)barbeiro, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwTheadIdprod // cating necessário

Page 11: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

);

if (BThreads[i]) printf("Barbeiro %d criada Id= %0x \n", i, dwTheadIdprod);

}//FOR

//CRIAÇÃO DAS THREADS DOS CLIENTES

for (i=0;i<NCLIENTES; ++i){

CThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)cliente, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwThreadIdcons // cating necessário

);

if (CThreads[i]) printf("Cliente %d criada Id= %0x \n", i, dwThreadIdcons);

}//FOR

//CHECA ERRO

dwRetprod = WaitForMultipleObjects(NBARBEIRO, BThreads,TRUE,INFINITE);

CheckForError((dwRetprod >= WAIT_OBJECT_0) && (dwRetprod < WAIT_OBJECT_0 +

NCLIENTES));

dwRetcons = WaitForMultipleObjects(NCLIENTES, CThreads,TRUE,INFINITE);

CheckForError((dwRetcons >= WAIT_OBJECT_0) && (dwRetcons < WAIT_OBJECT_0 +

NCLIENTES));

//APARGA A REFERENCIA DAS THEADS

for (i=0; i<NBARBEIRO; ++i){

GetExitCodeThread(BThreads[i], &dwExitCodeprod);

CloseHandle(BThreads[i]); // apaga referência ao objeto

} // for

for (i=0; i<NCLIENTES; ++i){

GetExitCodeThread(CThreads[i], &dwExitCodecons);

CloseHandle(CThreads[i]); // apaga referência ao objeto

} // for

//APAGA A REFERENCIA DOS SEMAFAROS

CloseHandle(SCLIENTES );

CloseHandle(SBARBEIROS);

CloseHandle(SMUTEX);

CloseHandle(LMUTEX);

printf("\nAcione uma tecla para terminar\n");

_getch(); // // Pare aqui, caso não esteja executando no ambiente MDS

Page 12: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

return EXIT_SUCCESS;

} // main

DWORD WINAPI barbeiro(LPVOID i)

{

LONG lOldValue;

Sleep(1000);

do{

//CONTROLA O BARBEIRO

WaitForSingleObject(SBARBEIROS, INFINITE);

ESTADO = ESTADO -1;

Sleep(1000);//TEMPO DE CORTE DO CABELO

printf("Barbeiro TERMINO cabelo de um cliente!\n");

//ACIONA O CLIENTE A LEVANTAR DA CADEIRA DO BARBEIRO

ReleaseSemaphore(LMUTEX, 1, &lOldValue);

//ACIONA O CLIENTE A SENTA NA CADEIRA DO BARBEIRO

ReleaseSemaphore(SMUTEX, 1, &lOldValue);

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc

DWORD WINAPI cliente(LPVOID i)

{

LONG lOldValue;

do{

//CONTROLA ENTRADA DE CLIENTES

WaitForSingleObject(SCLIENTES, INFINITE);

Sleep(2000); //CONTROLA TEMPO DE ENTRADA DE CADA CLIENTE

printf("Cliente ENTRA!\n");

//SE TIVER CADEIRA SENTA

if (ESTADO < NCADEIRAS){

// SE NAO TEM CLIENTE DORME

if (ESTADO==0)

printf("BARBEIRO DORMINDO\n ");

else

printf("Cliente %d Senta na cadeira de Espera!\n",i);

ESTADO = ESTADO +1;

//ACORDA UM CLIENTE PARA ENTRAR NA BARBERIA

Page 13: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

ReleaseSemaphore(SCLIENTES, 1, &lOldValue);

//CONTROLA A CADEIRA DO BARBEIRO (SENTA)

WaitForSingleObject(SMUTEX, INFINITE);

//ACORDA O BARBEIRO

ReleaseSemaphore(SBARBEIROS, 1, &lOldValue);

printf("Cliente %d Senta na Cadeira do Barbeiro\n", i);

//CONTROLA A CADEIRA DO BABEIRO (LEVANTA)

WaitForSingleObject(LMUTEX, INFINITE);

}//for

//SE NAO TIVER CADEIRAS VAI EMBORA

else{

//ACORDA UM CLIENTE PARA ENTRAR NA BARBERIA

ReleaseSemaphore(SCLIENTES, 1, &lOldValue);

printf("Cliente %d saiu da barbearia porque estava lotada!\n", i);

}//else

}while(TRUE);

_endthreadex(0);

return(0);

}//BoxFunc

4.4. Fumantes

Um sistema possui 3 processos fumantes inveterados. Cada fumante prepara cigarros e

os fuma em um loop infinito. Para fumar um cigarro, três ingredientes são necessários:

papel, tabaco e fósforos. Um dos processos fumantes tem tabaco, o outro papel e o outro

fósforos. O agente tem um suprimento infinito dos três ingredientes. O agente coloca dois

dos ingredientes escolhidos aleatoriamente sobre a mesa. O fumante que possui o terceiro

ingrediente pode então fumar o seu cigarro. Após fumar, este processo sinaliza o agente

que então escolhe dois novos ingredientes e o processo continua. Resolva o problema

usando semáforos. O processo fumante solicita os recursos de que necessita e é atendido

quando o recurso estiver disponível.

Observe que não existe memória global compartilhada!

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#include <process.h> // _beginthreadex() e _endthreadex()

#include <conio.h> // _getch

#define _CHECKERROR 1 // Ativa função CheckForError

#include "CheckForError.h"

Page 14: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

// Casting para terceiro e sexto parâmetros da função _beginthreadex

typedef unsigned (WINAPI *CAST_FUNCTION)(LPVOID);

typedef unsigned *CAST_LPDWORD;

//DEFINE O NUMERO DE FUMANTES

#define N 3

#define A 1

//ENUMERA OS INGREDIENTES

#define PAPEL 0

#define TABACO 1

#define FOSFORO 2

int ale = 0; //NUMERO ALEATORIO DO AGENTE

//HANDLE DOS SEMAFAROS

DWORD WINAPI AGENTE(int);

DWORD WINAPI FUMANTES(int);

HANDLE MUTEX;

HANDLE SPAPEL;

HANDLE STABACO;

HANDLE SFOSFORO;

int main()

{

//HANDLE DAS THREADS

HANDLE FThreads[N];

HANDLE AThreads[1];

DWORD dwThreadIdcons;

DWORD dwExitCodecons = 0;

DWORD dwRetcons;

DWORD dwThreadIda;

DWORD dwExitCodea = 0;

DWORD dwReta;

int i;

MUTEX = CreateSemaphore(NULL,1,1,"MUTEX");

SPAPEL = CreateSemaphore(NULL,0,1,"PAPEL");

Page 15: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

STABACO = CreateSemaphore(NULL,0,1,"TABACO");

SFOSFORO = CreateSemaphore(NULL,0,1,"FOSFORO");

//CRIA AS TRHEADS DOS FUMANTES

for (i=0;i<N; ++i){

FThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)FUMANTES, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwThreadIdcons // cating necessário

);

if (FThreads[i]) printf("FUMANTES %d criada Id= %0x \n", i, dwThreadIdcons);

}//FOR

//CRIA A THREDAS DO AGENTE

for (i=0;i<A; ++i){

AThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)AGENTE, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwThreadIda // cating necessário

);

if (AThreads) printf("AGENTE criada Id= %0x \n", dwThreadIda);

}//FOR

dwRetcons = WaitForMultipleObjects(N, FThreads,TRUE,INFINITE);

CheckForError((dwRetcons >= WAIT_OBJECT_0) && (dwRetcons < WAIT_OBJECT_0 + N));

dwReta = WaitForMultipleObjects(A, AThreads,TRUE,INFINITE);

CheckForError((dwReta >= WAIT_OBJECT_0) && (dwReta < WAIT_OBJECT_0 + A));

for (i=0; i<N; ++i){

GetExitCodeThread(FThreads[i], &dwExitCodecons);

CloseHandle(FThreads[i]); // apaga referência ao objeto

}// for

for (i=0; i<A; ++i){

GetExitCodeThread(AThreads, &dwExitCodea);

CloseHandle(AThreads);//apaga referencia ao objeto threads

}// for

Page 16: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

//apaga referneica ao objeto semafaro

CloseHandle(MUTEX);

CloseHandle(SPAPEL);

CloseHandle(STABACO);

CloseHandle(SFOSFORO);

printf("\nAcione uma tecla para terminar\n");

_getch(); // // Pare aqui, caso não esteja executando no ambiente MDS

return EXIT_SUCCESS;

} // main

DWORD WINAPI FUMANTES(int i){

int p;

LONG lOldValue;

Sleep(1000);

do{

//ANUNCIA QUE FUMANTE - PAPEL QUER FUMAR

if (i==PAPEL){

WaitForSingleObject(SPAPEL, INFINITE);

printf("FUMANDO - PEPEL \n");

}

//ANUNCIA QUE FUMANTE - TABACO QUER FUMAR

if (i==TABACO){

WaitForSingleObject(STABACO, INFINITE);

printf("FUMANDO - TABACO \n");

}

//ANUNCIA QUE FUMANTE - FOSFORO QUER FUMAR

if (i==FOSFORO){

WaitForSingleObject(SFOSFORO, INFINITE);

printf("FUMANDO - FOSFORO \n");

}

Sleep(1000);//PARA PARA FUMAR

printf("Para de Fumar Aciona o Agente\n\n");

//ACORDA O AGENTE

ReleaseSemaphore(MUTEX,1,&lOldValue);

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc

Page 17: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

DWORD WINAPI AGENTE(int i){

Sleep(1000);

LONG lOldValue;

int p;

do{

//ANUNCIA QUE O AGENTE QUE ADICIONAR INGREDIENTE

WaitForSingleObject(MUTEX, INFINITE);

ale = rand()%N ;

//AGENTE COLOCA INGREDIENTE ACORDA FUMANTE FOSFORO

if (ale == TABACO){

printf("Agente coloca PAPEL e FOSFORO \n");

//ACORDA O FUMANTE TABACO

ReleaseSemaphore(STABACO, 1, &lOldValue);

}

//AGENTE COLOCA INGREDIENTE ACORDA FUMANTE PAPEL

if (ale == FOSFORO){

printf("Agente coloca TABACO e PAPEL \n");

//ACORDA O FUMANTE FORSFORO

ReleaseSemaphore(SFOSFORO, 1, &lOldValue);

}

//AGENTE COLOCA INGREDIENTE ACORDA FUMANTE TABACO

if (ale == PAPEL){

printf("Agente coloca FOSFORO e TABACO \n");

//ACORDA O FUMANTE PAPEL

ReleaseSemaphore(SPAPEL, 1, &lOldValue);

}

}while(TRUE);

_endthreadex(0);

return(0);

}

4.5.Jantar dos Selvagens

Uma tribo de selvagens janta em conjunto, retirando missionários assados (para diminuir

o colesterol) de um grande pote que comporta até M missionários. Quando um selvagem

deseja comer ele se serve do pote, a menos que o pote esteja vazio. Se o pote está vazio,

o selvagem acorda um cozinheiro e espera até que este tenha assado mais missionários e

enchido o pote. Nos programas abaixo, substitua os marcadores em itálico por instruções

em pseudo linguagem de modo a garantir a perfeita sincronização entre cozinheiro e

selvagens.

#define N 10 //DEFINE OS SELVAGENS

#define M 5 //DEFINE OS missionários

Page 18: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

typedef unsigned (WINAPI *CAST_FUNCTION)(LPVOID);

typedef unsigned *CAST_LPDWORD;

//DECLARA OS SEMAFAROS

HANDLE cozinha;

HANDLE comida;

HANDLE mutex;

HANDLE enchendo;

//DECLARA AS THREADS

HANDLE Cozinheiro;

HANDLE Canibal[N];

//DECLARA AS FUNÇÕES

DWORD WINAPI Canibais(LPVOID);

DWORD WINAPI Cozinha(int);

int i=0;

int count = 0;

int main(){

DWORD dwThreadId;

DWORD dwExitCode = 0;

DWORD dwRet;

int i;

//CIRA OS SEMAFAROS

comida = CreateSemaphore(NULL, N, N , "Comida");

cozinha = CreateSemaphore(NULL, 0, 1 , "Cozinha");

mutex = CreateSemaphore(NULL, 1, 1 , "Mutex");

enchendo = CreateSemaphore(NULL,0,1,"Enchendo");

//CRIA AS THREADS CANIBAIS

for(i=0; i < N; i++){

Canibal[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)Canibais,

(LPVOID)i,

0,

(CAST_LPDWORD)&dwThreadId );

Page 19: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

if (Canibal[i]) printf("Thread %d criada com Id= %0x \n", 0,

dwThreadId);

}

//CRIA AS THREADS COZINHEIRO

Cozinheiro = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)Cozinha,

(LPVOID)0,

0,

(CAST_LPDWORD)&dwThreadId );

if (Cozinheiro) printf("Thread %d criada com Id= %0x \n", 0, dwThreadId);

for (i=0; i<N; ++i) {

dwRet = WaitForSingleObject(Canibal[i], INFINITE);

CheckForError(dwRet == WAIT_OBJECT_0);

GetExitCodeThread(Canibal[i], &dwExitCode);

printf("thread %d terminou com codigo de saida %d\n", i, dwExitCode);

CloseHandle(Canibal[i]); // apaga referência ao objeto

}

Sleep(10000);

CloseHandle(Canibal[0]);

printf("\nAcione uma tecla para terminar\n");

/*FIM DAS THREADS*/

/*FECHAMENTO DO HANDLE DOS SEMAFOROS*/

CloseHandle(comida);

CloseHandle(cozinha);

CloseHandle(mutex);

CloseHandle(enchendo);

/*FIM DO FECHAMENTO DO HANDLE DOS SEMAFOROS*/

getch(); }

DWORD WINAPI Cozinha(int index) {

LPLONG sc,sb,sm;

while(TRUE){

//ENTRADA DOS SELVAGENS PARA COMER

WaitForSingleObject(comida,INFINITE);

Page 20: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

//CONTROLA A IDA NO POTE

WaitForSingleObject(mutex, INFINITE);

Sleep(1000);

//SE MISSIONARIOS MAIOR O IGUAL A M CHAMA COZINHEIRO

count++;

printf("Selvagem %d foi ao pote\n", i);

i = (i+1)%N;

Sleep(1000);

if (count >= M){

printf("Pote VAZIO\n");

printf("Selvagem %d chama cozinheiro\n", i);

//SOLICITA O COZINHEIRO

ReleaseSemaphore(cozinha,1,sb);

WaitForSingleObject(enchendo,INFINITE);

count = 0;

}

printf("Selvagem Comeu\n");

printf("Selvagem Descansa\n");

//ACORDA O SELVAGEM PARA IR AO POTE

ReleaseSemaphore(mutex,1,sb);

}

_endthreadex(0);

return(0);

}

DWORD WINAPI Canibais(LPVOID index) {

LPLONG sc,sb,sm;

while(TRUE){

//CHAMA O COZINHEIRO

WaitForSingleObject(cozinha,INFINITE);

printf("Cozinhario Enche POTE\n");

Sleep(2000);

//ENCHE O POTE

for (i=0;i<M;i++){

ReleaseSemaphore(comida,1,sb);

}

ReleaseSemaphore(enchendo,1,sb);

}

} //

Page 21: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

4.6.Montanha Russa

Suponha que existam N processos do tipo passageiro e um processo do tipo carro de

montanha russa. Os passageiros esperam repetitivamente para dar uma volta no carro que

comporta C passageiro, C < N. Entretanto o carro só começa o seu trajeto se todos os

lugares estão ocupados. Use semáforos para criar os protocolos de entrada e saída da

seção crítica dos processos passageiro e carro. Conforme temos o algoritmo demostrado.

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#include <process.h> // _beginthreadex() e _endthreadex()

#include <conio.h> // _getch

#define _CHECKERROR 1 // Ativa função CheckForError

#include "CheckForError.h"

// Casting para terceiro e sexto parâmetros da função _beginthreadex

typedef unsigned (WINAPI *CAST_FUNCTION)(LPVOID);

typedef unsigned *CAST_LPDWORD;

//LEMBRANDO C<N

#define N 15 //DEFINE NUMEROS DE PASSAGEIROS

#define C 5*A //DEFINE NUMEROS DE CADEIRAS

#define A 2 //DEFINE A QUANTIDADE DE CARROS

int count = 0;

int espera=0;

//DEFINE SEMAFAROS

HANDLE EMUTEX;

HANDLE SMUTEX;

HANDLE CARRO;

//DEFINE FUNÇÕES

DWORD WINAPI PASSAGEIRO(LPVOID);

DWORD WINAPI CARROS(LPVOID); // declaração da função

int main()

{

int p;

DWORD dwThreadIdcons, dwTheadIdprod;

DWORD dwExitCodecons = 0, dwExitCodeprod = 0;

DWORD dwRetcons, dwRetprod;

int i;

//DEFINE TRHEADS

Page 22: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

HANDLE PThreads[N];

HANDLE CThreads[A];

//CRIA SEMARAFOS

EMUTEX = CreateSemaphore(NULL,1,1,"MUTEX");

CARRO= CreateSemaphore(NULL,0,A,"CARRO");

SMUTEX = CreateSemaphore(NULL,0,1,"PASSAGEIROS");

//CRIA THREADS

for (i=0; i<N; ++i) {

PThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)PASSAGEIRO, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwTheadIdprod // cating necessário

);

if (PThreads[i]) printf("Passageiros %d criada Id= %0x \n", i, dwTheadIdprod);

}

//CRIA THREADS CARRO

for (i=0;i<A; ++i){

CThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION) CARROS, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwThreadIdcons // cating necessário

);

if (CThreads[i]) printf("Carro %d criada Id= %0x \n", i, dwThreadIdcons);

}

//CHECA THREADS

dwRetprod = WaitForMultipleObjects(N, PThreads,TRUE,INFINITE);

CheckForError((dwRetprod >= WAIT_OBJECT_0) && (dwRetprod < WAIT_OBJECT_0 + N));

dwRetcons = WaitForMultipleObjects(A, CThreads,TRUE,INFINITE);

CheckForError((dwRetcons >= WAIT_OBJECT_0) && (dwRetcons < WAIT_OBJECT_0 +

A));

//APAGA REFERENCIA DAS THREADS

for (i=0; i<N; ++i){

GetExitCodeThread(PThreads[i], &dwExitCodeprod);

CloseHandle(PThreads[i]); // apaga referência ao objeto

} // for

Page 23: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

//APAGA REFERENCIA DA THREADS

for (i=0; i<A; ++i){

GetExitCodeThread(CThreads[i], &dwExitCodecons);

CloseHandle(CThreads[i]); // apaga referência ao objeto

} // for

//APAGA REFERENCIA DOS SEMAFAROS

CloseHandle(EMUTEX);

CloseHandle(CARRO);

CloseHandle(SMUTEX);

printf("\nAcione uma tecla para terminar\n");

_getch(); // // Pare aqui, caso não esteja executando no ambiente MDS

return EXIT_SUCCESS;

} // main

DWORD WINAPI PASSAGEIRO(LPVOID j)

{

LONG lOldValue;

Sleep(1000); // da um tempo para criar todo mundo e aumentar a concorrência

do{

//CONTROLA A ESPERA DE PASSAGEIROS EM FILA

WaitForSingleObject(EMUTEX, INFINITE);

Sleep(1000);//CONTROLE DE ENTRADA DE CADA PASSAGIRO

count++; //CONTA A QUANTIDADE DE PASSAGEIROS

//SE MENOR QUE A CAPACIDADE ENTRA PASSAGEIRO

if (count<C){

//ATIVA A ENTRADA DO PASSAGEIRO

ReleaseSemaphore(EMUTEX, 1, &lOldValue);

printf("%d Passageiros ENTROU\n", j);

//ESPERA DE CARRO CHEGAR

WaitForSingleObject(SMUTEX, INFINITE);

}

//SE IGUAL A CAPACIDADE ENTRA PASSAGEIRO E ACIONA O CARRO

if (count==C){

ReleaseSemaphore(EMUTEX, 1, &lOldValue);

printf("%d Passageiros ENTROU\n", j);

ReleaseSemaphore(CARRO, A, &lOldValue);

//ESPERA DE CARRO CHEGAR

Page 24: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

WaitForSingleObject(SMUTEX, INFINITE);

}

//SE MENOR QUE A CAPACIDADE PASSAGEIRO AGUARDA

if (count>C){

ReleaseSemaphore(EMUTEX, 1, &lOldValue);

printf("%d Passageiros AGUARDAM o Carro\n", j);

}

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc

DWORD WINAPI CARROS(LPVOID j){

LONG lOldValue;

int i;

Sleep(1000);// da um tempo para criar todo mundo e aumentar a concorrência

do{

printf("Carro Espera Passageiros\n");

//ACORDA O CARRO QUANDO ACIONADO

WaitForSingleObject(CARRO,INFINITE);

printf("Carro CHEIO ---- SAIU ----\n");

Sleep(1000);//ESPERA CARRO DA VOLTA

printf("Carro Chego Passageiros Saindo\n");

Sleep(1000);//ESPERA SAIDA DOS PASSAGERIOS

//AVISA QUE CHEGO

for (i=0;i<C; ++i){

ReleaseSemaphore(SMUTEX, 1, &lOldValue);

}

printf("TODOS OS PASSAGEIROS SAIRAM\n");

count=0;//APOS PASSAGEIROS SAIREM ZERA O CONTADOR

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc

4.7.Filme

Em uma determinado Stand uma feira, um demonstrador apresenta um filme sobre a vida

de Hoare, quando 10 pessoas chegam, o demonstrador fecha o pequeno auditório que não

comporta mais do que essa plateia. Novos candidatos a assistirem o filme devem espera

a próxima exibição. Esse filme faz muito sucesso com um grupo grande de Fãs (de bem

mais de 10 pessoas), que permanecem na feira só assistindo o filme seguidas vezes. Cada

vez que um desses fãs consegue assistir uma vez o filme por completo, ele vai telefonar

para casa para contar alguns detalhes novos para a sua mãe. Depois de telefonar ele volta

Page 25: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

mais uma vez ao stand para assistir ao filme outra vez. Usando semáforos, modelo o

processo fã e o processo demonstrador. Lembrando que existem muitos fãs e apenas um

demonstrador. Como cada fã é muito ardoroso, uma vez que ele chega ao stand são sai

dali até assistir ao filme. Suponha que haja muitos telefones disponíveis na feira e,

portanto que a tarefa de telefonar para casa não impõe nenhuma necessidade de

sincronização. Segue o algoritmo.

#define WIN32_LEAN_AND_MEAN

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#include <process.h> // _beginthreadex() e _endthreadex()

#include <conio.h> // _getch

#define _CHECKERROR 1 // Ativa função CheckForError

#include "CheckForError.h"

// Casting para terceiro e sexto parâmetros da função _beginthreadex

typedef unsigned (WINAPI *CAST_FUNCTION)(LPVOID);

typedef unsigned *CAST_LPDWORD;

#define STAND 10 //DEFINE A CAPACIDADE

#define NFAS 11 //DEFINE A QUANTIDADE DE FAS

#define NDEMONSTRADOR 1 // DEFINE O NUMERO DE DEMONSTRADOR

HANDLE SFAS; //SEMAFARO DE FAS

HANDLE EMUTEX; //SEMAFARO CONTROLA ENTRADA DOS FAS

HANDLE SMUTEX; //SEMAFARO CONTROLA SAIDA DOS FAS

HANDLE SDEMONSTRADOR;

int cont=0;

DWORD WINAPI FA(LPVOID); // DECLARAÇÃO DA FUNÇÃO FA

DWORD WINAPI DEMONSTRADOR(LPVOID); // DECLARAÇÃO DA FUNÇÃO DEMOSTRADRO

int main()

{

HANDLE BThreads[NFAS]; //THEADS FÃS

HANDLE CThreads[NDEMONSTRADOR]; //THEADS DEMONSTRDOR

int i;

DWORD dwThreadIdcons, dwTheadIdprod;

DWORD dwExitCodecons = 0, dwExitCodeprod = 0;

DWORD dwRetcons, dwRetprod;

Page 26: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

//CRIAÇÃO DOS SEMAFAROS

SDEMONSTRADOR = CreateSemaphore(NULL,0,1,"SDEMONSTRADOR");

EMUTEX = CreateSemaphore(NULL,1,1,"ENTRA");

SMUTEX = CreateSemaphore(NULL,0,STAND,"SAI");

//CRIAÇÃO DA THREADS DO FÃS

for (i=0; i<NFAS; ++i) {

BThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)FA, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwTheadIdprod // cating necessário

);

if (BThreads[i]) printf("FAS %d chega no STAND Id= %0x \n", i, dwTheadIdprod);

}

//CRIAÇÃO DAS THREADS DOS DEMONSTRADOR

for (i=0;i<NDEMONSTRADOR; ++i){

CThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)DEMONSTRADOR, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwThreadIdcons // cating necessário

);

if (CThreads[i]) printf("DEMONSTRADOR %d criada Id= %0x \n", i,

dwThreadIdcons);

}

//APARGA A REFERENCIA DAS THEADS

dwRetprod = WaitForMultipleObjects(NFAS, BThreads,TRUE,INFINITE);

CheckForError((dwRetprod >= WAIT_OBJECT_0) && (dwRetprod < WAIT_OBJECT_0 +

NFAS));

dwRetcons = WaitForMultipleObjects(NDEMONSTRADOR, CThreads,TRUE,INFINITE);

CheckForError((dwRetcons >= WAIT_OBJECT_0) && (dwRetcons < WAIT_OBJECT_0 +

NDEMONSTRADOR));

for (i=0; i<NFAS; ++i){

GetExitCodeThread(BThreads[i], &dwExitCodeprod);

Page 27: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

CloseHandle(BThreads[i]); // apaga referência ao objeto

} // for

for (i=0; i<NDEMONSTRADOR; ++i){

GetExitCodeThread(CThreads[i], &dwExitCodecons);

CloseHandle(CThreads[i]); // apaga referência ao objeto

} // for

//APAGA A REFERENCIA DOS SEMAFAROS

CloseHandle(EMUTEX);

CloseHandle(SMUTEX);

CloseHandle(SDEMONSTRADOR);

printf("\nAcione uma tecla para terminar\n");

_getch(); // // Pare aqui, caso não esteja executando no ambiente MDS

return EXIT_SUCCESS;

} // main

DWORD WINAPI FA(LPVOID J)

{

LONG lOldValue;

Sleep(1000); //tempo para Criação das Trheads

do{

//CONTROLA ENTRADA DOS FANS

WaitForSingleObject(EMUTEX, INFINITE);

Sleep(100);//TEMPO PARA ENTRADA DE FANS

cont++;//CONTADOR DE FANS

//SE CONTADOR FOR MENOR QUE CAPACIDADE NO STAND ENTRA

if(cont<STAND){

printf("FAN %d Entra -- %d STAND\n", J, cont);

ReleaseSemaphore(EMUTEX, 1, &lOldValue);

WaitForSingleObject(SMUTEX, INFINITE);

printf("%d FAN Saiu - LIGA para a MAE e Volta\n", J);

}

//SE CONTADOR FOR IGUAL ENTRA E ACIONA O DEMOTRADOR

if (cont==STAND){

printf("FAN %d Entra -- %d STAND\n", J, cont);

ReleaseSemaphore(SDEMONSTRADOR, 1, &lOldValue);

ReleaseSemaphore(EMUTEX, 1, &lOldValue);

WaitForSingleObject(SMUTEX, INFINITE);

printf("%d FAN Saiu - LIGA para a MAE e Volta\n", J);

Sleep(100);

Page 28: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

}

//SE CONTADOR FOR MENOR FAN AGUARDA SUA VEZ

if (cont>STAND){

printf("FAN %d AGUARDANDO\n",J);

}

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc

DWORD WINAPI DEMONSTRADOR(LPVOID J)

{

LONG lOldValue;

int t;

do{

WaitForSingleObject(SDEMONSTRADOR, INFINITE);

printf("%d ENTRARAM\n", cont);

printf("Fecha o STAND ASSISTI Filme 'A VIDA DE HOARE\n");

Sleep(1000);

ReleaseSemaphore(SMUTEX, STAND, &lOldValue);

cont =0;

ReleaseSemaphore(EMUTEX, 1, &lOldValue);

}while(TRUE);

_endthreadex(0);

return(0);

}

4.8.Pombo Correio

Um pombo correio leva 20 mensagens entre os locais A e B, mas só quando o número de

mensagens acumuladas chega a 20. Inicialmente, o pombo fica em A esperando que

existam 20 mensagens para carregar, e dormindo enquanto não houver. Quando as

mensagens chegam a 20, o pombo deve levar exatamente 20 mensagens de A para B, e

em seguida volta para a. Caso existam outras 20 mensagens, ele parte imediatamente;

caso contrário, ele corem de novo até que existem as 20 mensagens. As mensagens são

escritas em um post-it pelos usuários; cada usuário, quando tem uma mensagem pronta,

cola sua mensagem na mochila do pombo. Caso o pombo tenha uma mensagem pronta,

cola sua mensagem na mochila do pombo. Caso o pombo tenha partido, ele deve espera

o seu retorno para cola a mensagem na mochila. Conforme algoritmo com os comentários que se segue.

#define WIN32_LEAN_AND_MEAN

Page 29: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#include <process.h> // _beginthreadex() e _endthreadex()

#include <conio.h> // _getch

#define _CHECKERROR 1 // Ativa função CheckForError

#include "CheckForError.h"

// Casting para terceiro e sexto parâmetros da função _beginthreadex

typedef unsigned (WINAPI *CAST_FUNCTION)(LPVOID);

typedef unsigned *CAST_LPDWORD;

#define NMENSAGENS 20 //DEFINE A CAPACIDADE DE MENSAGENS

#define NUSUARIOS 25 //DEFINE A QUANTIDADE DE USUARIOS

#define NPOMBO 1 // DEFINE O NUMERO DE POMBO

HANDLE SPOMBO; //SEMAFARO POMBO

HANDLE EMUTEX; //SEMAFARO CONTROLA ENTRADA DOS USUARIOS

HANDLE CMUTEX; //SEMAFARO PARA COLOCAR NA MOCHILA

int cont=0;

DWORD WINAPI POMBO(LPVOID); // DECLARAÇÃO DA FUNÇÃO POMBO

DWORD WINAPI USUARIOS(LPVOID); // DECLARAÇÃO DA FUNÇÃO USUARIOS

int main()

{

HANDLE BThreads[NPOMBO]; //DECLARAÇÃO THEADS POMBO

HANDLE CThreads[NUSUARIOS]; //THEADS USUARIOS

int i;

DWORD dwThreadIdcons, dwTheadIdprod;

DWORD dwExitCodecons = 0, dwExitCodeprod = 0;

DWORD dwRetcons, dwRetprod;

//CRIAÇÃO DOS SEMAFAROS

SPOMBO = CreateSemaphore(NULL,0,NPOMBO,"POMBO");

EMUTEX = CreateSemaphore(NULL,1,1,"TIRA");

CMUTEX = CreateSemaphore(NULL,1,1,"COLOCA");

//CRIAÇÃO DAS THREADS

for (i=0; i<NPOMBO; ++i) {

BThreads[i] = (HANDLE) _beginthreadex(

Page 30: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

NULL,

0,

(CAST_FUNCTION)POMBO, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwTheadIdprod // cating necessário

);

if (BThreads[i]) printf("PONBO %d Id= %0x \n", i, dwTheadIdprod);

}

//CRIAÇÃO DAS THREADS

for (i=0;i<NUSUARIOS; ++i){

CThreads[i] = (HANDLE) _beginthreadex(

NULL,

0,

(CAST_FUNCTION)USUARIOS, // casting necessário

(LPVOID)i,

0,

(CAST_LPDWORD)&dwThreadIdcons // cating necessário

);

if (CThreads[i]) printf("USUARIOS %d criada Id= %0x \n", i, dwThreadIdcons);

}

//APARGA A REFERENCIA DAS THEADS

dwRetprod = WaitForMultipleObjects(NPOMBO, BThreads,TRUE,INFINITE);

CheckForError((dwRetprod >= WAIT_OBJECT_0) && (dwRetprod < WAIT_OBJECT_0 +

NPOMBO));

dwRetcons = WaitForMultipleObjects(NUSUARIOS, CThreads,TRUE,INFINITE);

CheckForError((dwRetcons >= WAIT_OBJECT_0) && (dwRetcons < WAIT_OBJECT_0 +

NUSUARIOS));

for (i=0; i<NPOMBO; ++i){

GetExitCodeThread(BThreads[i], &dwExitCodeprod);

CloseHandle(BThreads[i]); // apaga referência ao objeto

} // for

for (i=0; i<NUSUARIOS; ++i){

GetExitCodeThread(CThreads[i], &dwExitCodecons);

CloseHandle(CThreads[i]); // apaga referência ao objeto

} // for

Page 31: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

//APAGA A REFERENCIA DOS SEMAFAROS

CloseHandle(SPOMBO);

CloseHandle(CMUTEX);

CloseHandle(EMUTEX);

printf("\nAcione uma tecla para terminar\n");

_getch(); // // Pare aqui, caso não esteja executando no ambiente MDS

return EXIT_SUCCESS;

} // main

DWORD WINAPI USUARIOS(LPVOID J)

{

LONG lOldValue;

Sleep(1000);//TEMPO PARA CRIAÇÃO DAS THREADS

do{

//CONTROLA A ENTRADA DOS USUARIOS

WaitForSingleObject(CMUTEX, INFINITE);

Sleep(100);//DA UM TEMPO PARA CADA USUARIO

cont++;

//SE CONTADOR FOR MENOR QUE MENSAGEM USUARIO COLA A MENSAGEM

if(cont<NMENSAGENS){

printf("Usuario %d Cola Mensagem -- %d na Mochila\n",J, cont);

//ACORDA UM USUARIO

ReleaseSemaphore(CMUTEX, 1, &lOldValue);

}

//COLOCA A MENSAGEM E ACORDA O POMBO

if (cont==NMENSAGENS){

printf("Usuario %d Cola Mensagem -- %d na Mochila\n",J, cont);

printf("%d Coladas na Mochila\n",cont);

//ACORDA O POMBO

ReleaseSemaphore(SPOMBO, 1, &lOldValue);

}

}while(TRUE);

_endthreadex(0);

return(0);

} // BoxFunc

DWORD WINAPI POMBO(LPVOID J)

{

LONG lOldValue;

int t;

Sleep(1000); //TEMPO PARA CRIAÇÃO DAS THREADS

Page 32: Sema Faro

FUNDAÇÃO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CIÊNCIA E TECNOLOGIA DE MONTES CLAROS

DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO CURSO DE ENGENHARIA DE COMPUTAÇÃO

do{

printf("Pombo Dormindo\n");

//POMBO ESPERA SER ACIONADO

WaitForSingleObject(SPOMBO, INFINITE);

printf("Acorda o Pombo\n");

printf("Pombo Sai de A para B\n");

printf("%d USUARIOS AGUARDANDO\n",NUSUARIOS);

Sleep(1000);//TEMPO PARA VIAGEM DO POMBO

printf("Pombo sai de B para A\n");

printf("POMBO CHEGA\n");

cont=0; //ZERA O CONTADOR E REINICIA A COLAGEM DA MENSAGEM

//ACORDA O USUARIOS APOS A CHEGADA DO POMBO

ReleaseSemaphore(CMUTEX, 1, &lOldValue);

}while(TRUE);

_endthreadex(0);

return(0);

}//BoxFunc

5. CONCLUSÃO

Percebe-se a importância dos semáforos na implementação de processos com recursos

compartilhando, confirmando sua eficiência e conseguindo satisfazer as quatros

condições. Com essa pratica foi possível dar um fechamento na aprendizagem do

conteúdo lecionado, dando uma aprofundada no conhecimento.

Para encontrar a lógica a ser usada em cada problema deu um pouco de trabalho mas a

implementação dos códigos fluíram muito bem. Todas os problemas implementados

executaram sem erros e deram uma reposta satisfatória com relação aos problemas

propostos, que neste trabalho o uso do semáforo mostrou-se bastante dinâmico

percebendo que pode ser usadas em diversas situação e problemas que poderá surgir.

6. BIBLIOGRAFIA

FILHO, Constantino Seixas; Szuster, Marcelo. Programação Multithreaded em ambiente

Windows NT© - Uma Visão de Automação. 1999.

MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de Sistemas

Operacionais. Ed. 4. LTC Editora. 2007. 304p.