Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>//std
- #include <windows.h>//Sleep & thread
- #include <string.h>//Strlen
- #include <malloc.h>//Malloc
- //Tamanho da fila de impressao
- #define TAMANHO_FILA 5//Limitar impede o consumo de memoria pelo thread2
- #define DELAYMS_IMPRESSAO 1000//Delay de impressao
- /* DECLARAÇÕES GLOBAIS */
- using namespace std;
- //~~thread's
- DWORD WINAPI runn_thr1(void *);//thread 1 (gerenciador de fila)
- DWORD WINAPI runn_thr2(void *);//thread 2 (impressor)
- void init_threads();//inicia threads
- HANDLE thr1,thr2[TAMANHO_FILA], vblock_gfila, vblock_imp;//variaveis do thread
- bool wait_thread(HANDLE);
- //~~menu
- int menu();
- //~~variaveis globais - uso ativo de thread
- bool add_fila = false; //sinalizador - adicionar arquivo a fila
- bool imp_arquivo = false;//sinalizador - imprimir arquivo na fila
- int fila_count = 0;//Armazena quantidade de arquivos na fila
- int thr2id = 0;
- //Arquivo a ser impresso
- struct Arquivo
- {
- //Dados comuns de um arquivo a ser impresso
- char *nome;
- //Limpar variaveis
- void clear(){
- nome = NULL;
- };
- //Altera nome do arquivo - ja aloca de acordo com a string enviada
- void set(const char *str){
- nome = (char *)malloc(sizeof(char *)*strlen(str));
- strcpy(nome, str);
- };
- };
- //Arquivo temporario - usado para passar dados, do processo principal para o thread 1, depois para o thread 2
- Arquivo file_temp;
- Arquivo **fila_thr2;//usar esse objeto para armazenar as informacões dos 'arquivos' da fila
- /* FIM DECLARAÇÕES GLOBAIS */
- int main(){
- init_threads();//inicia threads
- menu();//menu
- return 0;
- }
- //Mostra menu na tela, executa funções do menu
- int menu(){
- int r = 0,l = 1;
- //Aloca vetor da fila e thread2
- fila_thr2 = (Arquivo **)malloc(sizeof(Arquivo *)*TAMANHO_FILA);
- for(int i = 0; i < TAMANHO_FILA; i++){
- fila_thr2[i] = NULL;
- thr2[i] = NULL;
- }
- while(l){
- //Limpa dados de entrada
- fflush(stdin);
- //Texto do menu
- cout << " == MENU ==" << endl;
- cout << "1 - Imprimir arquivos em fila" << endl;
- cout << "2 - Adicionar arquivo a fila de impressao" << endl;
- cout << "3 - Ver fila de impressao" << endl;;
- cout << "0 - Sair " << endl;
- cout << "\n>";
- cin >> r;
- if(r == 0) break;
- fflush(stdin);
- switch(r){
- case 1://Imprimir arquivos da fila
- imp_arquivo = true;//Sinaliza impressao
- break;
- case 2://Adicionar arquivo
- {
- //Fila cheia
- if(fila_count >= TAMANHO_FILA){
- cout << "Fila cheia! Tente mais tarde." << endl;
- break;
- }
- //Alocando memoria - struct Arquivo
- file_temp.nome = (char *)malloc(sizeof(char *)*128);
- //Questionario
- cout << "Digite o nome do arquivo(128):";
- cin.getline(file_temp.nome,128);
- //Enviar para thread 1
- add_fila = true;
- }
- break;
- case 3://Mostrar Fila
- {
- if(fila_count <= 0){
- cout << endl << "Fila vazia! Tente mais tarde." << endl;
- break;
- }
- for(int i = 0; i < TAMANHO_FILA; i++){
- if(fila_thr2[i] != NULL){
- cout << "["<< i <<"] - "<< fila_thr2[i]->nome << endl;
- }
- }
- }
- break;
- case 0:
- l = 0;
- break;
- }
- }
- }
- /* Gerencia fila da impressora */
- DWORD WINAPI runn_thr1(void *){
- Arquivo thr_tmp; // Armazena arquivo temporario, mesmo que mudo o global(file_temp)
- while(1){//Loop eterno até que seja interrompido ou um arquivo esteja para ser adicionado
- if(add_fila){//Solicitação para adicionar na fila
- add_fila = false;
- //Copia dados do arquivo para o struct thr_tmp do thread1
- thr_tmp.set(file_temp.nome);
- Sleep(1000);//Delay de solicitação - so assim é possivel perceber o uso do MUTEX
- thr2id = -1;//slot thread
- //Encontra um slot vazio para colocar o arquivo na fila
- for(int i = 0; i < TAMANHO_FILA; i++){
- if(fila_thr2[i] == NULL){
- cout << "Slot "<<i<<" livre."<<endl;
- //Aloca vetores - Arquivo *
- fila_thr2[i] = (Arquivo *)malloc(sizeof(Arquivo *));
- thr2id = i;
- //Adiciona nome do arquivo na estrutura da fila
- fila_thr2[i]->set(thr_tmp.nome);
- cout << "Arquivo "<< fila_thr2[i]->nome <<" adicionado a fila!" << endl;
- //Cria thread 2
- thr2[i] = CreateThread(NULL,0,runn_thr2,NULL,0,NULL);
- //Aumenta contagem da fila
- fila_count++;
- break;
- }
- }
- //Valor se encontra 0 pois não foi modificado acima
- if(thr2id < 0){
- cout << "Nao foi possivel adicionar arquivo "<< thr_tmp.nome <<" a fila."<< endl;
- }
- }
- }
- }
- /* Impressora */
- DWORD WINAPI runn_thr2(void *){
- int id = thr2id;//Slot do thread
- thr2id = 0;//Limpa variavel
- int sleeptime = id * DELAYMS_IMPRESSAO;//Delay de impressao
- while(1){
- //Imprimir arquivos - so quando receber o sinal do usuario
- if(imp_arquivo){
- // --- Impedir multiuso dos threads 2 - não sobrecarregar a impressora
- vblock_imp = CreateSemaphore(NULL,10,10,NULL);
- if(!wait_thread(vblock_imp)){
- while(1){
- vblock_imp = CreateSemaphore(NULL,10,10,NULL);
- if(wait_thread(vblock_imp))break;
- }
- }
- // ---- ---------------------------------------------------------------
- Sleep(sleeptime);//Esse tempo impede que um Slot atravesse a vez do outro
- cout << "Arquivo "<< fila_thr2[id]->nome <<" imprimido!\n"<<endl;//Output
- fila_thr2[id] = NULL;//Esvazia slot da fila
- fila_count--;//Aumenta contagem
- ReleaseSemaphore(vblock_imp,10,NULL);//Desbloqueia Semafaro
- imp_arquivo = false;
- break;
- }
- }
- }
- //Inicia thread 1
- void init_threads(){
- thr1 = CreateThread(NULL,0,runn_thr1,NULL,0,NULL);//Cria thread 1
- }
- //Funcao que verifica o resultado de um semafaro
- //Retorna:
- //true -> semafaro verde
- //false -> semafaro vermelho
- bool wait_thread(HANDLE smp){
- DWORD wres = WaitForSingleObject(smp,0L);
- switch(wres){
- case WAIT_OBJECT_0:
- //Continuar thread
- return true;
- break;
- case WAIT_TIMEOUT:
- //Thread não pode continuar
- return false;
- break;
- default:
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement