Académique Documents
Professionnel Documents
Culture Documents
TRABALHO FINAL
THREADS E SEMÁFOROS
THREADS E SEMÁFOROS
SUMÁRIO
1. INTRODUÇÃO .................................................................................................................. 3
2. OBJETIVOS ...................................................................................................................... 4
3. METODOLOGIA............................................................................................................... 4
3.1 SOFTWARE UTILIZADO.................................................................................................... 4
3.2 PROBLEMA DO PRODUTOR CONSUMIDOR .............................................................. 4
3.3 JANTAR DOS FILÓSOFOS ............................................................................................... 8
3.4 SALÃO DE BARBEIRO .................................................................................................... 12
3.5 FUMANTES ......................................................................................................................... 15
3.6 MONTANHA RUSSA ........................................................................................................ 18
4. CONCLUSÃO ................................................................................................................. 22
5. REFERENCIAS BIBLIOGRAFICAS ........................................................................... 23
3
1. INTRODUÇÃO
2. OBJETIVOS
3. METODOLOGIA
Neste problema temos a seguinte situação, onde há uma thread que irá
produzir dados e outra thread que irá realizar a retirada destes dados. O
problema que temos nesta situação se dá pela interação entre as duas threads,
pois neste processo, caso não seja empregado o método correto, pode ocorrer o
acesso a seção crítica pelas duas threads, o produtor poderá criar dados em
excesso, ou o consumidor poderá ficar em espera aguardando os dados a serem
produzidos.
Afim de, realizar a tarefa de criação de dados apenas quando houver espaço
em buffer e a retirada apenas quando houver dados disponíveis, foi desenvolvido
o seguinte algoritmo.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
5
#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;
cheios=CreateSemaphore(NULL,Min_Pos,Max_Pos,"EXCLUSAO");
vazios=CreateSemaphore(NULL,20,20,"EXCLUSAO");
CheckForError(hThreads[1]);
if (hThreads[1]) printf("Thread %d criada com Id= %0x \n\n", 1, dwThreadId);
Sleep(2000);
ResumeThread(hThreads[1]);
ResumeThread(hThreads[0]);
dwRet = WaitForMultipleObjects(2,hThreads,TRUE,INFINITE);
CheckForError((dwRet >= WAIT_OBJECT_0) && (dwRet < WAIT_OBJECT_0 + 2));
return EXIT_SUCCESS;
} // main
_endthreadex((DWORD) index);
return(0);
} // produtor
“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 regras
a serem obedecidas sã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.”
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
char opcao;
int estado[5]={1,1,1,1,1}; // 1 pensado 2 com fome 3 comendo;
HANDLE Mutex;
HANDLE Semaforo[5];
HANDLE hThread[6];
void Pega_talheres(int i);
void Devolve_talheres(int i);
9
Semaforo[0] = CreateSemaphore(NULL,0,1,"Sem0");
Semaforo[1] = CreateSemaphore(NULL,0,1,"Sem1");
Semaforo[2] = CreateSemaphore(NULL,0,1,"Sem2");
Semaforo[3] = CreateSemaphore(NULL,0,1,"Sem3");
Semaforo[4] = CreateSemaphore(NULL,0,1,"Sem4");
for(int x=0;x<5;x++){
char *aux=(char*)x;
hThread[x] = CreateThread(NULL,0,Filosofo,aux,0,NULL);
if(hThread) printf("Thread %d criada com sucesso\n",x);
else
printf("ERRO na criacao da Thread %d\n",x);
}
hThread[5] = CreateThread(NULL,0,Menu,NULL,0,NULL);
if(hThread) printf("Thread Menu criada com sucesso\n");
else
printf("ERRO na criacao da Thread Menu\n");
do{
opcao = _getch();
if(opcao=='a')
estado[0]=2;
if(opcao=='b')
estado[1]=2;
if(opcao=='c')
estado[2]=2;
if(opcao=='d')
estado[3]=2;
if(opcao=='e')
estado[4]=2;
}while(opcao!='s');
10
WaitForMultipleObjects(5,hThread,TRUE,INFINITE);
for(int x=0;x<5;x++){
CloseHandle(hThread[x]);
CloseHandle(Semaforo[x]);
}
CloseHandle(hThread[5]);
CloseHandle(Mutex);
system("pause");
return 0;
}
}while(opcao!='s');
11
ExitThread(0);
return 0;
}
void Pega_talheres(int i)
{
WaitForSingleObject(Mutex,INFINITE);
Test(i);
ReleaseMutex(Mutex);
WaitForSingleObject(Semaforo[i],INFINITE);
}
void Devolve_talheres(int i)
{
int esquerda = (i+5-1)%5;
int direita = (i+1)%5;
WaitForSingleObject(Mutex,INFINITE);
estado[i]=1;
Test(esquerda);
Test(direita);
ReleaseMutex(Mutex);
}
void Test(int i)
{
int esquerda = (i+5-1)%5;
int direita = (i+1)%5;
if(estado[i]==2 && estado[esquerda]!=3 && estado[direita]!=3)
{
estado[i]=3;
ReleaseSemaphore(Semaforo[i],1,NULL);
}
}
a seqüência que cada filósofo irá jantar, utilizando para isso um Mutex, cinco
semáforos, seis threads e outras três tarefas (pega talheres, devolve talheres
e test).
Sendo assim para realizar a organização da ação dos filósofos no jantar,
criamos duas threads uma que define o que ele deve fazer (Filosofo) e a outra
define o que ele está fazendo (Menu)
Tendo declarado as funções realizamos a criação das mesmas juntamente
com a inserção de um check de erro para certificar da criação das threads.
A partir de cada opção definimos o estado respectivo, utilizando a função
“do”.
Logo após declaramos o comportamento das threads criadas para definir
a ação de cada filósofo obedecendo os critérios definidos pelo enunciado do
problema, sendo que através dos estados e das ações realizadas pelos
filósofos conseguimos evitar que algum dos critérios solicitados fosse
desobedecidos.
#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "pthread.h"
#include "semaphore.h"
/* protótipos */
void* barber(void *arg);
void* customer(void *arg);
void cut_hair();
void customer_arrived();
void get_haircut();
void giveup_haircut();
int main() {
sem_init(&customers, TRUE, 0);
sem_init(&barbers, TRUE, 0);
sem_init(&mutex, TRUE, 1);
pthread_t b, c;
return 0;
}
pthread_exit(NULL);
}
pthread_exit(NULL);
14
void cut_hair() {
printf("Barbeiro estah cortando o cabelo de alguem!\n");
sleep(3);
}
void customer_arrived() {
printf("Cliente chegou para cortar cabelo!\n");
}
void get_haircut() {
printf("Cliente estah tendo o cabelo cortado!\n");
}
void giveup_haircut() {
printf("Cliente desistiu! (O salao estah muito cheio!)\n");
}
A solução aqui apresentada usa três semáforos: customers, que conta
os clientes á espera de atendimento (exceto o cliente que está na cadeira de
barbeiro, que não está esperando); barbers, o número de barbeiros (0 ou 1)
que estão ociosos à espera de clientes, e mutex, que é usado para exclusão
mútua.
Precisamos ainda de uma variável, waiting, que também conta os
clientes à espera de atendimento. É essencialmente uma cópia de customers.
A razão de se ter waiting é que não há uma maneira de ler o valor atual
do semáforo. Nessa solução, um cliente que entra na barbearia deve contar o
número de clientes à espera de atendimento. Se este for menor que o número
de cadeiras, ele ficará, do contrário, ele sairá.
Na solução, quando chega de manhã para trabalhar, o barbeiro
executa o método barber, que o leva a bloquear sobre o semáforo customers,
que inicialmente está em 0. O barbeiro então vai dormir, e permanece
dormindo até que o primeiro cliente apareça.
Quando chega, o cliente executa customers e inicia obtendo mutex
para entrar em uma região crítica. Se um outro cliente chega logo em
seguida, o segundo nada pode fazer até que o primeiro libere o mutex. O
cliente então verifica se o número de clientes à espera é menor que o número
de cadeiras. Se não for, ele liberará o mutex e sairá sem cortar o cabelo.
Se houver uma cadeira disponível, o cliente incrementará a variável
inteira waiting. Ele faz então um up no semáforo customers que acorda o
barbeiro. Nesse ponto, o barbeiro o pega, faz alguma limpeza e começa a
cortar o cabelo. Quando termina o corte de cabelo, o cliente sai do
15
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h> // _beginthreadex() e _endthreadex()
#include <conio.h> // _getch
int i,op1=1,k=10;
HANDLE agente;
HANDLE S1;
HANDLE S2;
HANDLE S3;
HANDLE MUTEX;
LPLONG aux1,aux2,aux3,aux4,aux5,aux6,aux7;
int main()
16
{
HANDLE hThreads[4];
DWORD dwThreadId;
DWORD dwExitCode = 0;
DWORD dwRet;
agente=CreateSemaphore(NULL,1,1,"Agente");
S1=CreateSemaphore(NULL,0,1,"Semaphore_fumante1");
S2=CreateSemaphore(NULL,0,1,"Semaphore_fumante2");
S3=CreateSemaphore(NULL,0,1,"Semaphore_fumante3");
MUTEX=CreateMutex(NULL,FALSE,"EXCLUSAO");
CheckForError(hThreads[0]);
if (hThreads[0]) printf("Thread %d criada com Id= %0x \n\n", 0, dwThreadId);
CheckForError(hThreads[1]);
if (hThreads[1]) printf("Thread %d criada com Id= %0x \n\n", 1, dwThreadId);
CheckForError(hThreads[2]);
if (hThreads[2]) printf("Thread %d criada com Id= %0x \n\n", 2, dwThreadId);
SuspendThread(hThreads[3]);
CheckForError(hThreads[3]);
if (hThreads[3]) printf("Thread %d criada com Id= %0x \n\n", 3, dwThreadId);
Sleep(2000);
ResumeThread(hThreads[0]);
ResumeThread(hThreads[1]);
ResumeThread(hThreads[2]);
ResumeThread(hThreads[3]);
dwRet = WaitForMultipleObjects(4,hThreads,TRUE,INFINITE);
CheckForError((dwRet >= WAIT_OBJECT_0) && (dwRet < WAIT_OBJECT_0 + 2));
}
CloseHandle(agente);
CloseHandle(S1);
CloseHandle(S2);
CloseHandle(S3);
CloseHandle(MUTEX);
return EXIT_SUCCESS;
}
while(k>0){
WaitForSingleObject(agente,INFINITE);
printf("\n\nAgente Fornecedor: \n1-papel e tabaco\n2-tabaco e fosforo\n3-fosforo e papel ");
scanf("%d",&op1);
if(op1==1){
ReleaseSemaphore(S1,1,aux1);
}
if(op1==2){
ReleaseSemaphore(S2,1,aux2);
}
if(op1==3){
ReleaseSemaphore(S3,1,aux3);
}
if((op1>3)||(op1<=0)){
printf("OPCAO INVALIDA\n");
ReleaseSemaphore(agente,1,aux7);
}
k--;
}
_endthreadex((DWORD) index);
return(0);
18
return(0);
}
return(0);
}
return(0);
}
#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"
HANDLE passageiro;
HANDLE carro;
HANDLE MUTEX;
int sentado=0;
LPLONG aux1,aux2;
int main()
{
HANDLE hThreads[2];
DWORD dwThreadId;
DWORD dwExitCode = 0;
DWORD dwRet;
passageiro=CreateSemaphore(NULL,10,10,"Passageiro");
carro=CreateSemaphore(NULL,0,1,"Carro");
MUTEX=CreateMutex(NULL,FALSE,"EXCLUSAO");
CheckForError(hThreads[0]);
if (hThreads[0]) printf("Thread %d criada com Id= %0x \n\n", 0, dwThreadId);
CheckForError(hThreads[1]);
if (hThreads[1]) printf("Thread %d criada com Id= %0x \n\n", 1, dwThreadId);
Sleep(2000);
20
ResumeThread(hThreads[1]);
ResumeThread(hThreads[0]);
dwRet = WaitForMultipleObjects(2,hThreads,TRUE,INFINITE);
CheckForError((dwRet >= WAIT_OBJECT_0) && (dwRet < WAIT_OBJECT_0 + 2));
int f=0;
for (f=0; f<2; ++f) {
GetExitCodeThread(hThreads[f], &dwExitCode);
printf("thread %d terminou: codigo=%d\n\n",f,dwExitCode);
CloseHandle(hThreads[f]); // apaga referência ao objeto
} // for
CloseHandle(carro);
CloseHandle(passageiro);
CloseHandle(MUTEX);
WaitForSingleObject(carro,INFINITE);
WaitForSingleObject(MUTEX,INFINITE);
printf("\n\n UOOOOOOOOOOOL.. Dando vooolta... UOL UOL UOL /o/ /o/ /o/ /o/ /o/ \n");
Sleep(2000);
for(i=0;i<10;i++){
ReleaseSemaphore(passageiro,1,aux1);
}
printf("\n THE END \n");
Sleep(1000);
ReleaseMutex(MUTEX);
k--;
}
_endthreadex((DWORD) index);
return(0);
}
WaitForSingleObject(passageiro,INFINITE);
WaitForSingleObject(MUTEX,INFINITE);
printf("\n Passageiro %d entrou",cont);
cont++;
Sleep(500);
p=p+1;
if(p==5){
printf("\n Vamos Lá!");
21
ReleaseSemaphore(carro,1,aux2);
p=0;
Sleep(2000);
}
k--;
ReleaseMutex(MUTEX);
}
_endthreadex((DWORD) index);
return(0);
}
22
4. CONCLUSÃO
5. REFERENCIAS BIBLIOGRAFICAS