Você está na página 1de 32

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

1. INTRODUO Uma Thread (Linha ou Escalonamento de execuo) uma forma de um processo que dividir a si mesmo em duas mais tarefas que podem ser executadas concorrentemente. Possibilitando implementar aplicaes concorrente com uma maior eficincia. Uma thread permite, por exemplo, que o usurio de um programa utilize uma funcionalidade do ambiente enquanto outras linhas de execuo realizam outros clculos e operaes. Com isso temos possibilidade de implementa um processo de vrias formas, uma delas e a possibilidade de interlaar dois ou mais programas, sendo que ao executar certos trechos crticos, pode-se ter alguns comportamentos instvel sendo que seus resultados dependem integralmente de uma ordem de execuo, que na viso de um programados isso no pode ocorrer. Para sarnarmos isso deve-se usar uma tcnica em programao concorrente para evitar que dois processos ou Threads tenham acesso simultaneamente a um recurso compartilhado (acesso esse denominado seco crtica) que a Excluso Mtua. Muitos mtodos forma usados para garantir a excluso mtua, mas em 1968 Dijkstra criou o conceito de Semforos, e tambm sendo capazes de resolver uma grande variedades de problemas. O Semforo um objeto com apenas um membro de dados representados por um inteiro sem sinal e dois mtodos que definem s nicas operaes permitidas: WAIT(S), se um positivo, decrementa o valor de S. se S e igual a zero, suspende a thread no semforo. SIGNAL(S), acorda uma Thread que esteja suspensa no semforo. Caso no haja nenhuma, incrementa o valor de S. Com isso possvel satisfazer as quatro propriedades bsicas para a implementao de programao concorrente utilizando threads: Excluso mtua, ausncia de deadlock, ausncia de inanio e chegada na ausncia de conteno.

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++.

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

4. DESENVOLVIMENTO Conforme solicitado, foram implementados os seguintes problemas: 1. Produtor e Consumidor, 2. Filsofos, 3. Salo 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 execues testadas, e seu funcionamento foi todo comentado no prprio cdigo e redigido no corpo deste trabalho. 4.1 Produtor e Consumidor Neste programa foi implementado conforme implementao abaixo com seus comentrios inseridos. Sendo que para alterao do Buffer para poder de ir de 10 a 24 posies de armazenamento, basta alterar o valor de N. Analisando a o algoritmo pode se provar as propriedades, sendo que o produtor no pode inserir dados em um buffer cheio, o consumidor no pode consumir dados no buffer, ausncia de deadlock e no ocorre inanio 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 funo CheckForError #include "CheckForError.h" // Casting para terceiro e sexto parmetros da funo _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 //DECARAO DOS SEMAFAROS HANDLE VAZIOS; HANDLE CHEIOS;

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO // DECLARAO DAS FUNES DWORD WINAPI Produtor(LPVOID); DWORD WINAPI Consumidor(LPVOID); int Buffer[N]; // Buffer circular int InIndex = 0; // ndice para posio livre para insero de dados int OutIndex = 0; // ndice para posio 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 necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwTheadIdprod // cating necessrio ); 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 necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwThreadIdcons // cating necessrio

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO ); 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 referncia ao objeto } // for

for (i=0; i<cons; ++i){ GetExitCodeThread(CThreads[i], &dwExitCodecons); CloseHandle(CThreads[i]); // apaga referncia ao objeto } // for //APAGA REFERENCIA DOS SEMAFAROS CloseHandle(CHEIOS); CloseHandle(VAZIOS); printf("\nAcione uma tecla para terminar\n"); _getch(); // // Pare aqui, caso no 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 concorrncia do{ Sleep(1000); //ESPERA QUE HAJA ESPAO LIVRE WaitForSingleObject(VAZIOS, INFINITE); Sleep(100); //INSERE DADO NO BUFFER

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO Buffer[InIndex] = Produzir; cont++; printf("O Produtor %d Produziu!\n", cont); // Aponta prxima posio 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 concorrncia 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 POSIO OCUPADA OutIndex = (OutIndex + 1)%N; //SINALIZA VAZIO ReleaseSemaphore(VAZIOS, 1, &lOldValue); }while(TRUE); _endthreadex(0); return(0); } // BoxFunc.

4.2.Filsofos Um dos problema clssicos mais famosos da histria da computao. Cinco filsofos esto sentados em torno de uma mesa circular, que tem em seu centro um prato inesgotvel de sushis (na histria 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 filsofos est um talher japons (hashi). Cada filsofo para comer deve pegar dois talheres, uma vez que difcil equilibrar um sushi em um nico talher. Cada filsofo realiza um loop infinito em que pensa, toma os talheres um a um, come e devolve os talheres mesa. As regrasa serem obedecidas so:

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

P1: Dois filsofos no podem segurar um mesmo talher simultaneamente. P2: O filsofo s come, quando tem dois talheres P3: No deve haver deadlock, situao em que nenhum dos filsofos consegue comer. P4: No pode haver inanio (neste caso inanio propriamente dita), isto , um filsofo 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 comentrios 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 #include "CheckForError.h" // Ativa funo CheckForError

// Casting para terceiro e sexto parmetros da funo _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 //ENUMERAO DOS ESTADOS #define PENSANDO 0 #define COM_FOME 1 #define COMENDO 2 int Estado[N]; //BUFFER DOS ESTADOS //DECLAO DOS SEMAFAROS HANDLE MUTEX; HANDLE S[N]; //FUNES DE TESTES E MOSTRA void Pega_talheres(int); void Devolve_talheres(int); void Test(int); void Mostrar(void); DWORD WINAPI Filosofo(int); // declarao da funo int main()

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO { HANDLE hThreads[N]; //DECLARAO DA THREAD int p; DWORD dwThreadId; DWORD dwExitCode = 0; DWORD dwRet; char filosofo; //CRIAO DO MUTEX MUTEX = CreateMutex(NULL, FALSE, "filosofo"); CheckForError(MUTEX); //CRIAO SEMAFARO for (p=0; p<N; ++p){ S[p] = CreateSemaphore(NULL,N,1,"filosofos"); } //CRIAO DAS THREADS for (p=0; p<N; ++p){ hThreads[p] = (HANDLE) _beginthreadex( NULL, 0, (CAST_FUNCTION)Filosofo, // casting necessrio (LPVOID)p, 0, (CAST_LPDWORD)&dwThreadId // casting necessrio ); 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 referncia ao objeto } // for //APAGA O MUTEX CloseHandle(MUTEX); //APAGA OS SEMAFAROS

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO for (p=0; p<N; ++p){ CloseHandle(S[p]); } printf("\nAcione uma tecla para terminar\n"); _getch(); // // Pare aqui, caso no 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 concorrncia 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 filsofo esquerda Test(DIREITA); // Verifica se mudou estado do filsofo direita ReleaseMutex(MUTEX); } void Test(int j) { LONG lOldValue; if ((Estado[j] == COM_FOME) && (Estado[ESQUERDA] != COMENDO) && (Estado[DIREITA]!=COMENDO)) {

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO Estado[j]=COMENDO; Mostrar(); ReleaseSemaphore(S[j], 1, &lOldValue); // Se o filsofo tem os dois talheres disponveis, 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.Salo de Barbeiro Um salo de barbeiro tem uma cadeira de barbear, 5 cadeiras de espera, e um barbeiro. Quando no h clientes, o barbeiro se senta na cadeira de barbear e dorme. Um cliente chegando nesta situao prontamente atendido. Se o cliente chega e o barbeiro est ocupado, o cliente verifica o nmero de cadeiras de espera livres. Se existir alguma livre, o cliente se senta e espera, caso contrrio, vai embora. Gerencie o salo de barbeiro usando semforos. 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 #include "CheckForError.h" // Ativa funo CheckForError

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO // Casting para terceiro e sexto parmetros da funo _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 SALO #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); // DECLARAO DA FUNO CLIENTE DWORD WINAPI barbeiro(LPVOID); // DECLARAO DA FUNO 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; //CRIAO 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"); //CRIAO DA THREADS DO BARBEIRO for (i=0; i<NBARBEIRO; ++i) { BThreads[i] = (HANDLE) _beginthreadex( NULL, 0, (CAST_FUNCTION)barbeiro, // casting necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwTheadIdprod // cating necessrio

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO ); if (BThreads[i]) printf("Barbeiro %d criada Id= %0x \n", i, dwTheadIdprod); }//FOR //CRIAO DAS THREADS DOS CLIENTES for (i=0;i<NCLIENTES; ++i){ CThreads[i] = (HANDLE) _beginthreadex( NULL, 0, (CAST_FUNCTION)cliente, // casting necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwThreadIdcons // cating necessrio ); 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 referncia ao objeto } // for for (i=0; i<NCLIENTES; ++i){ GetExitCodeThread(CThreads[i], &dwExitCodecons); CloseHandle(CThreads[i]); // apaga referncia 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 no esteja executando no ambiente MDS

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

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

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO 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, trs ingredientes so necessrios: papel, tabaco e fsforos. Um dos processos fumantes tem tabaco, o outro papel e o outro fsforos. O agente tem um suprimento infinito dos trs ingredientes. O agente coloca dois dos ingredientes escolhidos aleatoriamente sobre a mesa. O fumante que possui o terceiro ingrediente pode ento fumar o seu cigarro. Aps fumar, este processo sinaliza o agente que ento escolhe dois novos ingredientes e o processo continua. Resolva o problema usando semforos. O processo fumante solicita os recursos de que necessita e atendido quando o recurso estiver disponvel. Observe que no existe memria 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 #include "CheckForError.h" // Ativa funo CheckForError

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

// Casting para terceiro e sexto parmetros da funo _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");

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO 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 necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwThreadIdcons // cating necessrio ); 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 necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwThreadIda // cating necessrio ); 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 referncia ao objeto }// for for (i=0; i<A; ++i){ GetExitCodeThread(AThreads, &dwExitCodea); CloseHandle(AThreads);//apaga referencia ao objeto threads }// for

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

//apaga referneica ao objeto semafaro CloseHandle(MUTEX); CloseHandle(SPAPEL); CloseHandle(STABACO); CloseHandle(SFOSFORO); printf("\nAcione uma tecla para terminar\n"); _getch(); // // Pare aqui, caso no 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

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO 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 missionrios assados (para diminuir o colesterol) de um grande pote que comporta at M missionrios. 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 missionrios e enchido o pote. Nos programas abaixo, substitua os marcadores em itlico por instrues em pseudo linguagem de modo a garantir a perfeita sincronizao entre cozinheiro e selvagens.
#define N 10 //DEFINE OS SELVAGENS #define M 5 //DEFINE OS missionrios

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO 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 FUNES 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

);

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO 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 referncia 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);

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO //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); } } //

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

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 comea o seu trajeto se todos os lugares esto ocupados. Use semforos para criar os protocolos de entrada e sada da seo crtica 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 #include "CheckForError.h" // Ativa funo CheckForError

// Casting para terceiro e sexto parmetros da funo _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 FUNES DWORD WINAPI PASSAGEIRO(LPVOID); DWORD WINAPI CARROS(LPVOID); // declarao da funo int main() { int p; DWORD dwThreadIdcons, dwTheadIdprod; DWORD dwExitCodecons = 0, dwExitCodeprod = 0; DWORD dwRetcons, dwRetprod; int i; //DEFINE TRHEADS

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO 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 necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwTheadIdprod // cating necessrio ); 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 necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwThreadIdcons // cating necessrio ); 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 referncia ao objeto } // for

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

//APAGA REFERENCIA DA THREADS for (i=0; i<A; ++i){ GetExitCodeThread(CThreads[i], &dwExitCodecons); CloseHandle(CThreads[i]); // apaga referncia ao objeto } // for //APAGA REFERENCIA DOS SEMAFAROS CloseHandle(EMUTEX); CloseHandle(CARRO); CloseHandle(SMUTEX); printf("\nAcione uma tecla para terminar\n"); _getch(); // // Pare aqui, caso no 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 concorrncia 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

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO 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 concorrncia 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 auditrio que no comporta mais do que essa plateia. Novos candidatos a assistirem o filme devem espera a prxima exibio. Esse filme faz muito sucesso com um grupo grande de Fs (de bem mais de 10 pessoas), que permanecem na feira s assistindo o filme seguidas vezes. Cada vez que um desses fs consegue assistir uma vez o filme por completo, ele vai telefonar para casa para contar alguns detalhes novos para a sua me. Depois de telefonar ele volta

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO

mais uma vez ao stand para assistir ao filme outra vez. Usando semforos, modelo o processo f e o processo demonstrador. Lembrando que existem muitos fs e apenas um demonstrador. Como cada f muito ardoroso, uma vez que ele chega ao stand so sai dali at assistir ao filme. Suponha que haja muitos telefones disponveis na feira e, portanto que a tarefa de telefonar para casa no impe nenhuma necessidade de sincronizao. 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 #include "CheckForError.h" // Ativa funo CheckForError

// Casting para terceiro e sexto parmetros da funo _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); // DECLARAO DA FUNO FA DWORD WINAPI DEMONSTRADOR(LPVOID); // DECLARAO DA FUNO DEMOSTRADRO int main() { HANDLE BThreads[NFAS]; //THEADS FS HANDLE CThreads[NDEMONSTRADOR]; //THEADS DEMONSTRDOR int i; DWORD dwThreadIdcons, dwTheadIdprod; DWORD dwExitCodecons = 0, dwExitCodeprod = 0; DWORD dwRetcons, dwRetprod;

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO //CRIAO DOS SEMAFAROS SDEMONSTRADOR = CreateSemaphore(NULL,0,1,"SDEMONSTRADOR"); EMUTEX = CreateSemaphore(NULL,1,1,"ENTRA"); SMUTEX = CreateSemaphore(NULL,0,STAND,"SAI"); //CRIAO DA THREADS DO FS for (i=0; i<NFAS; ++i) { BThreads[i] = (HANDLE) _beginthreadex( NULL, 0, (CAST_FUNCTION)FA, // casting necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwTheadIdprod // cating necessrio ); if (BThreads[i]) printf("FAS %d chega no STAND Id= %0x \n", i, dwTheadIdprod); } //CRIAO DAS THREADS DOS DEMONSTRADOR for (i=0;i<NDEMONSTRADOR; ++i){ CThreads[i] = (HANDLE) _beginthreadex( NULL, 0, (CAST_FUNCTION)DEMONSTRADOR, // casting necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwThreadIdcons // cating necessrio ); 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);

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO CloseHandle(BThreads[i]); } // for for (i=0; i<NDEMONSTRADOR; ++i){ GetExitCodeThread(CThreads[i], &dwExitCodecons); CloseHandle(CThreads[i]); // apaga referncia 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 no esteja executando no ambiente MDS return EXIT_SUCCESS; } // main DWORD WINAPI FA(LPVOID J) { LONG lOldValue; Sleep(1000); //tempo para Criao 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); // apaga referncia ao objeto

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO } //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 nmero de mensagens acumuladas chega a 20. Inicialmente, o pombo fica em A esperando que existam 20 mensagens para carregar, e dormindo enquanto no 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 contrrio, ele corem de novo at que existem as 20 mensagens. As mensagens so escritas em um post-it pelos usurios; cada usurio, 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 comentrios que se segue. #define WIN32_LEAN_AND_MEAN

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <process.h> // _beginthreadex() e _endthreadex() #include <conio.h> // _getch #define _CHECKERROR 1 // Ativa funo CheckForError #include "CheckForError.h" // Casting para terceiro e sexto parmetros da funo _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); // DECLARAO DA FUNO POMBO DWORD WINAPI USUARIOS(LPVOID); // DECLARAO DA FUNO USUARIOS int main() { HANDLE BThreads[NPOMBO]; //DECLARAO THEADS POMBO HANDLE CThreads[NUSUARIOS]; //THEADS USUARIOS int i; DWORD dwThreadIdcons, dwTheadIdprod; DWORD dwExitCodecons = 0, dwExitCodeprod = 0; DWORD dwRetcons, dwRetprod; //CRIAO DOS SEMAFAROS SPOMBO = CreateSemaphore(NULL,0,NPOMBO,"POMBO"); EMUTEX = CreateSemaphore(NULL,1,1,"TIRA"); CMUTEX = CreateSemaphore(NULL,1,1,"COLOCA"); //CRIAO DAS THREADS for (i=0; i<NPOMBO; ++i) { BThreads[i] = (HANDLE) _beginthreadex(

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO NULL, 0, (CAST_FUNCTION)POMBO, // casting necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwTheadIdprod // cating necessrio ); if (BThreads[i]) printf("PONBO %d Id= %0x \n", i, dwTheadIdprod); } //CRIAO DAS THREADS for (i=0;i<NUSUARIOS; ++i){ CThreads[i] = (HANDLE) _beginthreadex( NULL, 0, (CAST_FUNCTION)USUARIOS, // casting necessrio (LPVOID)i, 0, (CAST_LPDWORD)&dwThreadIdcons // cating necessrio ); 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 referncia ao objeto } // for for (i=0; i<NUSUARIOS; ++i){ GetExitCodeThread(CThreads[i], &dwExitCodecons); CloseHandle(CThreads[i]); // apaga referncia ao objeto } // for

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO //APAGA A REFERENCIA DOS SEMAFAROS CloseHandle(SPOMBO); CloseHandle(CMUTEX); CloseHandle(EMUTEX); printf("\nAcione uma tecla para terminar\n"); _getch(); // // Pare aqui, caso no esteja executando no ambiente MDS return EXIT_SUCCESS; } // main DWORD WINAPI USUARIOS(LPVOID J) { LONG lOldValue; Sleep(1000);//TEMPO PARA CRIAO 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 CRIAO DAS THREADS

FUNDAO EDUCACIONAL DE MONTES CLAROS FACULDADE DE CINCIA E TECNOLOGIA DE MONTES CLAROS DEPARTAMENTO DE ENGENHARIA DE COMPUTAO CURSO DE ENGENHARIA DE COMPUTAO 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. CONCLUSO Percebe-se a importncia dos semforos na implementao de processos com recursos compartilhando, confirmando sua eficincia e conseguindo satisfazer as quatros condies. Com essa pratica foi possvel dar um fechamento na aprendizagem do contedo lecionado, dando uma aprofundada no conhecimento. Para encontrar a lgica a ser usada em cada problema deu um pouco de trabalho mas a implementao dos cdigos fluram muito bem. Todas os problemas implementados executaram sem erros e deram uma reposta satisfatria com relao aos problemas propostos, que neste trabalho o uso do semforo mostrou-se bastante dinmico percebendo que pode ser usadas em diversas situao e problemas que poder surgir.

6. BIBLIOGRAFIA FILHO, Constantino Seixas; Szuster, Marcelo. Programao Multithreaded em ambiente Windows NT - Uma Viso de Automao. 1999. MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de Sistemas Operacionais. Ed. 4. LTC Editora. 2007. 304p.