repo: bufferCircular
consumidor
//consumidor #include <Windows.h> #include <tchar.h> #include <math.h> #include <stdio.h> #include <fcntl.h> #include <io.h> #include <time.h> //lidar com o random #define TAM_BUFFER_CIRUCLAR 10 //importante para os semáforos, numero de posicoes do buffer circular typedef struct { int id; int val; } CelulaBufferCircular; //estrutura de cada célula do buffer circular typedef struct { int numeroProdutores; int numeroConsumidores; int proximaPosicaoEscrita; //controlar int proximaPosicaoLeitura; //controlar CelulaBufferCircular buffer[TAM_BUFFER_CIRUCLAR]; } BufferCircular; //representação da memoria partilhada typedef struct { BufferCircular* memoriaPartilhada; HANDLE hSemaforoControlaEscrita; HANDLE hSemaforoControloLeitura; HANDLE hMutexControloExclusaoMutua; //mutex: exclusivo e partilhado por todos os produtores int controloDaThread; //flag, 1 sair, 0 caso contrário int idConsumidor; }DadosThreads; //a thread consumidor DWORD WINAPI ThreadConsumidor(LPVOID param) { DadosThreads* dados = (DadosThreads*)param; CelulaBufferCircular celBC; //teriam que ser vários fosse o caso de enviar para vários consumidores a informação de todos os produtores int contadorItensProduzidos = 0; int soma = 0; while (dados->controloDaThread == 0) { //ler no buffer circular, WaitForSingleObject( dados->hSemaforoControloLeitura, //existe uma posição para ler INFINITE ); //temos a garantia que temos uma posicção de escrita WaitForSingleObject( dados->hMutexControloExclusaoMutua, //existe uma posição para escrevermos INFINITE ); //temos a garantia que somos nos a ler //os dois estão desbloqueados e vamos ser o unico consumdior que vai ler CopyMemory( &celBC, //copiar &dados->memoriaPartilhada->buffer[dados->memoriaPartilhada->proximaPosicaoLeitura], //destino sizeof(CelulaBufferCircular) ); //a proxima posicao de escrita é incrementada dados->memoriaPartilhada->proximaPosicaoLeitura++; //cheguei ao limite volto à posicao 0 if (dados->memoriaPartilhada->proximaPosicaoLeitura == TAM_BUFFER_CIRUCLAR) { dados->memoriaPartilhada->proximaPosicaoLeitura = 0; } //libertar o mutex quando terminamos a leitura ReleaseMutex(dados->hMutexControloExclusaoMutua); //libtertar o semaforo de escrita //se ocupamos uma posição de leitura libertamos uma posição de escrita //e o consumidor espera por uma posição de leitura e desbloqueia uma posição de escrita ReleaseSemaphore(dados->hSemaforoControlaEscrita, 1, NULL); //apenas uma posição, 1 contadorItensProduzidos++; soma = soma + celBC.val; _tprintf(TEXT("\nConsumidor %d consumiu valor %d "), dados->idConsumidor, celBC.val); //Sleep(numero_aleatorio(2, 4) * 1000); } _tprintf(TEXT("\nConsumidor %d consumiu %d acumulado"), dados->idConsumidor, soma); return 0; } int _tmain(int argc, LPSTR argv[]) { HANDLE hFileMap; //mapeamento da memoria partilhada DadosThreads dados; #ifdef UNICODE _setmode(_fileno(stdin), _O_WTEXT); _setmode(_fileno(stdout), _O_WTEXT); _setmode(_fileno(stderr), _O_WTEXT); #endif //lidar com o random srand((unsigned int)time(NULL)); //os semaforos dados.hSemaforoControlaEscrita = CreateSemaphore( NULL, TAM_BUFFER_CIRUCLAR, TAM_BUFFER_CIRUCLAR, TEXT("SO2_MEMORIA_ESCRITA") ); if (dados.hSemaforoControlaEscrita == NULL) { _tprintf(TEXT("\nerro no hSemaforoControlaEscrita")); return 1; } dados.hSemaforoControloLeitura = CreateSemaphore(NULL, 0, //quantidade de posições iniciais, não existe nada para ser lido TAM_BUFFER_CIRUCLAR, //maximo de posições para serem lidas TEXT("SO2_MEMORIA_LEITURA") ); if (dados.hSemaforoControloLeitura == NULL) { _tprintf(TEXT("\nerro no hSemaforoControloLeitura")); return 1; } //exclusao mutua para os produtores dados.hMutexControloExclusaoMutua = CreateMutex(NULL, FALSE, TEXT("SO2_MUTEX_CONSUMIDOR")); if (dados.hMutexControloExclusaoMutua == NULL) { _tprintf(TEXT("\nerro no hMutexControloExclusaoMutua")); return 1; } hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, TEXT("SO2_MEMORIA_PARTILHADA")); int primeiroProcesso = FALSE; //se existir é aberto //se nao existe é nulo if (hFileMap == NULL) { //existe um problem é porque se calahar não existe //criar a memoria partilhada primeiroProcesso = TRUE; hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,//INVALID_HANDLE_VALUE ao inves de um ficheiro, faz o sistema isso NULL, PAGE_READWRITE, //nivel de protecão: lieura e escrita); 0, //dimensões da memoria partilhada: mais significativa sizeof(BufferCircular), //dimensões da memoria partilhada: menos significataiva TEXT("SO2_MEMORIA_PARTILHADA")//nome do file mapping: que vai ser criado e aberto pelos outros, nome em MACRO ); if (hFileMap == NULL) { _tprintf(TEXT("\nerro no CreateFileMapping")); return 1; } } dados.memoriaPartilhada = (BufferCircular*)MapViewOfFile( hFileMap, FILE_MAP_ALL_ACCESS, //permissoes, de leitura e escrita 0, //offsets: onde é mapeada 0, //0 para mapear até ao final 0 //0 para mapear até ao final ); if (dados.memoriaPartilhada == NULL) { _tprintf(TEXT("\nerro no MapViewOfFile")); return 1; } //inicialização: só deve ser feita quando a mem partilhada é criada, pois podemos ter N produtores. if (primeiroProcesso == TRUE) { dados.memoriaPartilhada->numeroConsumidores = 0; dados.memoriaPartilhada->numeroProdutores = 0; dados.memoriaPartilhada->proximaPosicaoEscrita = 0; dados.memoriaPartilhada->proximaPosicaoLeitura = 0; } //criar a thread dados.controloDaThread = 0; //exclusão mutua proque queremos aceder a algo que está em memoria partilhada WaitForSingleObject(dados.hMutexControloExclusaoMutua, INFINITE); //ir à memoria partilhada dados.memoriaPartilhada->numeroConsumidores++; dados.idConsumidor = dados.memoriaPartilhada->numeroConsumidores; //libertar o mutex ReleaseMutex(dados.hMutexControloExclusaoMutua); HANDLE hThread; TCHAR comando[100]; hThread = CreateThread(NULL, 0, ThreadConsumidor, &dados, 0, NULL); if (hThread != NULL) { _tprintf(TEXT("escreve qualquer coisa para sair")); _getts_s(comando, 100); dados.controloDaThread = 1; WaitForSingleObject(hThread, INFINITE); } UnmapViewOfFile(dados.memoriaPartilhada); //CloseHandle(); return 0; }
produtor
//produtor #include <Windows.h> #include <tchar.h> #include <math.h> #include <stdio.h> #include <fcntl.h> #include <io.h> #include <time.h> //lidar com o random #define TAM_BUFFER_CIRUCLAR 10 //importante para os semáforos, numero de posicoes do buffer circular typedef struct { int id; int val; } CelulaBufferCircular; //estrutura de cada célula do buffer circular typedef struct { int numeroProdutores; int numeroConsumidores; int proximaPosicaoEscrita; //controlar int proximaPosicaoLeitura; //controlar CelulaBufferCircular buffer[TAM_BUFFER_CIRUCLAR]; } BufferCircular; //representação da memoria partilhada typedef struct { BufferCircular* memoriaPartilhada; HANDLE hSemaforoControlaEscrita; HANDLE hSemaforoControloLeitura; HANDLE hMutexControloExclusaoMutua; //mutex: exclusivo e partilhado por todos os produtores int controloDaThread; //flag, 1 sair, 0 caso contrário int idProdutor; }DadosThreads; //lidar com o random int numero_aleatorio(int min, int max) { return rand() % (max - min + 1) + min; //valor entre min e max } //a trhead produtor DWORD WINAPI ThreadProdutor(LPVOID param) { DadosThreads* dados = (DadosThreads*)param; CelulaBufferCircular celBC; //teriam que ser vários fosse o caso de enviar para vários consumidores a informação de todos os produtores int contadorItensProduzidos = 0; while (dados->controloDaThread == 0) { celBC.id = dados->idProdutor; //produzir o item celBC.val = numero_aleatorio(10,99); //escrever no buffer circular, WaitForSingleObject( dados->hSemaforoControlaEscrita, //existe uma posição para escrevermos INFINITE ); //temos a garantia que temos uma posicção de escrita WaitForSingleObject( dados->hMutexControloExclusaoMutua, //existe uma posição para escrevermos INFINITE ); //temos a garantia que somos nos a escrever //os dois estão desbloqueados e vamos ser o unico produtor que vai escrever CopyMemory( &dados->memoriaPartilhada->buffer[dados->memoriaPartilhada->proximaPosicaoEscrita], //destino, copiar &celBC, sizeof(CelulaBufferCircular) ); //a proxima posicao de escrita é incrementada dados->memoriaPartilhada->proximaPosicaoEscrita++; //cheguei ao limite volto à posicao 0 if (dados->memoriaPartilhada->proximaPosicaoEscrita == TAM_BUFFER_CIRUCLAR) { dados->memoriaPartilhada->proximaPosicaoEscrita = 0; } //libertar o mutex ReleaseMutex(dados->hMutexControloExclusaoMutua); //libtertar o semaforo de leitura //se ocupamos uma posição de escrita libertamos uma posição de leitura //o produtor espera por uma posição de escrita e desbloqueia uma posição de leitura //e o consumidor espera por uma posição de leitura e desbloqueia uma posição de escrita ReleaseSemaphore(dados->hSemaforoControloLeitura, 1, NULL); //apenas uma posição, 1 contadorItensProduzidos++; _tprintf(TEXT("\nProdutor %d produziu valor %d "), dados->idProdutor, celBC.val); Sleep(numero_aleatorio(2, 4)*1000); } _tprintf(TEXT("\nProdutor %d produziu %d itens"), dados->idProdutor, contadorItensProduzidos); return 0; } int _tmain(int argc, LPSTR argv[]) { HANDLE hFileMap; //mapeamento da memoria partilhada DadosThreads dados; #ifdef UNICODE _setmode(_fileno(stdin), _O_WTEXT); _setmode(_fileno(stdout), _O_WTEXT); _setmode(_fileno(stderr), _O_WTEXT); #endif //lidar com o random srand((unsigned int)time(NULL)); //os semaforos dados.hSemaforoControlaEscrita = CreateSemaphore( NULL, TAM_BUFFER_CIRUCLAR, TAM_BUFFER_CIRUCLAR, TEXT("SO2_MEMORIA_ESCRITA") ); if (dados.hSemaforoControlaEscrita == NULL) { _tprintf(TEXT("\nerro no hSemaforoControlaEscrita")); return 1; } dados.hSemaforoControloLeitura = CreateSemaphore(NULL, 0, //quantidade de posições iniciais, não existe nada para ser lido TAM_BUFFER_CIRUCLAR, //maximo de posições para serem lidas TEXT("SO2_MEMORIA_LEITURA") ); if (dados.hSemaforoControloLeitura == NULL) { _tprintf(TEXT("\nerro no hSemaforoControloLeitura")); return 1; } //exclusao mutua para os produtores dados.hMutexControloExclusaoMutua = CreateMutex(NULL, FALSE, TEXT("SO2_MUTEX_PRODUTOR")); if (dados.hMutexControloExclusaoMutua == NULL) { _tprintf(TEXT("\nerro no hMutexControloExclusaoMutua")); return 1; } hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, TEXT("SO2_MEMORIA_PARTILHADA")); int primeiroProcesso = FALSE; //se existir é aberto //se nao existe é nulo if (hFileMap == NULL) { //existe um problem é porque se calahar não existe //criar a memoria partilhada primeiroProcesso = TRUE; hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,//INVALID_HANDLE_VALUE ao inves de um ficheiro, faz o sistema isso NULL, PAGE_READWRITE, //nivel de protecão: lieura e escrita); 0, //dimensões da memoria partilhada: mais significativa sizeof(BufferCircular), //dimensões da memoria partilhada: menos significataiva TEXT("SO2_MEMORIA_PARTILHADA")//nome do file mapping: que vai ser criado e aberto pelos outros, nome em MACRO ); if (hFileMap == NULL) { _tprintf(TEXT("\nerro no CreateFileMapping")); return 1; } } dados.memoriaPartilhada = (BufferCircular*)MapViewOfFile( hFileMap, FILE_MAP_ALL_ACCESS, //permissoes, de leitura e escrita 0, //offsets: onde é mapeada 0, //0 para mapear até ao final 0 //0 para mapear até ao final ); if (dados.memoriaPartilhada == NULL) { _tprintf(TEXT("\nerro no MapViewOfFile")); return 1; } //inicialização: só deve ser feita quando a mem partilhada é criada, pois podemos ter N produtores. if (primeiroProcesso == TRUE) { dados.memoriaPartilhada->numeroConsumidores = 0; dados.memoriaPartilhada->numeroProdutores = 0; dados.memoriaPartilhada->proximaPosicaoEscrita = 0; dados.memoriaPartilhada->proximaPosicaoLeitura = 0; } //criar a thread dados.controloDaThread = 0; //exclusão mutua proque queremos aceder a algo que está em memoria partilhada WaitForSingleObject(dados.hMutexControloExclusaoMutua, INFINITE); //ir à memoria partilhada dados.memoriaPartilhada->numeroProdutores++; dados.idProdutor = dados.memoriaPartilhada->numeroProdutores; //liberta ro mutex ReleaseMutex(dados.hMutexControloExclusaoMutua); HANDLE hThread; TCHAR comando[100]; hThread = CreateThread(NULL, 0, ThreadProdutor, &dados, 0, NULL); if (hThread != NULL) { _tprintf(TEXT("escreve qualquer coisa para sair")); _getts_s(comando, 100); dados.controloDaThread = 1; WaitForSingleObject(hThread, INFINITE); } UnmapViewOfFile(dados.memoriaPartilhada); //CloseHandle(); return 0; }
0 thoughts on “repo: bufferCircular”