Advertisement
Guest User

Untitled

a guest
Sep 13th, 2016
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.08 KB | None | 0 0
  1. #include <iostream>//std
  2. #include <windows.h>//Sleep & thread
  3. #include <string.h>//Strlen
  4. #include <malloc.h>//Malloc
  5.  
  6. //Tamanho da fila de impressao
  7. #define TAMANHO_FILA 5//Limitar impede o consumo de memoria pelo thread2
  8. #define DELAYMS_IMPRESSAO 1000//Delay de impressao
  9.  
  10. /* DECLARAÇÕES GLOBAIS */
  11. using namespace std;
  12.  
  13. //~~thread's
  14. DWORD WINAPI runn_thr1(void *);//thread 1 (gerenciador de fila)
  15. DWORD WINAPI runn_thr2(void *);//thread 2 (impressor)
  16.  
  17. void init_threads();//inicia threads
  18.  
  19.  
  20. HANDLE thr1,thr2[TAMANHO_FILA], vblock_gfila, vblock_imp;//variaveis do thread
  21.  
  22. bool wait_thread(HANDLE);
  23.  
  24. //~~menu
  25. int menu();
  26.  
  27. //~~variaveis globais - uso ativo de thread
  28. bool add_fila = false; //sinalizador - adicionar arquivo a fila
  29. bool imp_arquivo = false;//sinalizador - imprimir arquivo na fila
  30.  
  31. int fila_count = 0;//Armazena quantidade de arquivos na fila
  32. int thr2id = 0;
  33.  
  34. //Arquivo a ser impresso
  35. struct Arquivo
  36. {
  37. //Dados comuns de um arquivo a ser impresso
  38. char *nome;
  39.  
  40. //Limpar variaveis
  41. void clear(){
  42. nome = NULL;
  43. };
  44. //Altera nome do arquivo - ja aloca de acordo com a string enviada
  45. void set(const char *str){
  46. nome = (char *)malloc(sizeof(char *)*strlen(str));
  47. strcpy(nome, str);
  48. };
  49. };
  50. //Arquivo temporario - usado para passar dados, do processo principal para o thread 1, depois para o thread 2
  51. Arquivo file_temp;
  52. Arquivo **fila_thr2;//usar esse objeto para armazenar as informacões dos 'arquivos' da fila
  53.  
  54. /* FIM DECLARAÇÕES GLOBAIS */
  55.  
  56. int main(){
  57. init_threads();//inicia threads
  58. menu();//menu
  59.  
  60. return 0;
  61. }
  62.  
  63.  
  64. //Mostra menu na tela, executa funções do menu
  65. int menu(){
  66. int r = 0,l = 1;
  67.  
  68. //Aloca vetor da fila e thread2
  69. fila_thr2 = (Arquivo **)malloc(sizeof(Arquivo *)*TAMANHO_FILA);
  70.  
  71. for(int i = 0; i < TAMANHO_FILA; i++){
  72. fila_thr2[i] = NULL;
  73. thr2[i] = NULL;
  74. }
  75.  
  76. while(l){
  77. //Limpa dados de entrada
  78. fflush(stdin);
  79.  
  80. //Texto do menu
  81. cout << " == MENU ==" << endl;
  82. cout << "1 - Imprimir arquivos em fila" << endl;
  83. cout << "2 - Adicionar arquivo a fila de impressao" << endl;
  84. cout << "3 - Ver fila de impressao" << endl;;
  85. cout << "0 - Sair " << endl;
  86. cout << "\n>";
  87. cin >> r;
  88.  
  89. if(r == 0) break;
  90.  
  91.  
  92. fflush(stdin);
  93.  
  94. switch(r){
  95. case 1://Imprimir arquivos da fila
  96. imp_arquivo = true;//Sinaliza impressao
  97. break;
  98. case 2://Adicionar arquivo
  99. {
  100. //Fila cheia
  101. if(fila_count >= TAMANHO_FILA){
  102. cout << "Fila cheia! Tente mais tarde." << endl;
  103. break;
  104. }
  105. //Alocando memoria - struct Arquivo
  106. file_temp.nome = (char *)malloc(sizeof(char *)*128);
  107.  
  108. //Questionario
  109. cout << "Digite o nome do arquivo(128):";
  110. cin.getline(file_temp.nome,128);
  111.  
  112.  
  113. //Enviar para thread 1
  114. add_fila = true;
  115.  
  116. }
  117. break;
  118. case 3://Mostrar Fila
  119. {
  120. if(fila_count <= 0){
  121. cout << endl << "Fila vazia! Tente mais tarde." << endl;
  122. break;
  123. }
  124. for(int i = 0; i < TAMANHO_FILA; i++){
  125. if(fila_thr2[i] != NULL){
  126. cout << "["<< i <<"] - "<< fila_thr2[i]->nome << endl;
  127. }
  128. }
  129. }
  130. break;
  131. case 0:
  132. l = 0;
  133. break;
  134. }
  135. }
  136. }
  137. /* Gerencia fila da impressora */
  138. DWORD WINAPI runn_thr1(void *){
  139. Arquivo thr_tmp; // Armazena arquivo temporario, mesmo que mudo o global(file_temp)
  140.  
  141. while(1){//Loop eterno até que seja interrompido ou um arquivo esteja para ser adicionado
  142.  
  143. if(add_fila){//Solicitação para adicionar na fila
  144. add_fila = false;
  145.  
  146. //Copia dados do arquivo para o struct thr_tmp do thread1
  147. thr_tmp.set(file_temp.nome);
  148.  
  149. Sleep(1000);//Delay de solicitação - so assim é possivel perceber o uso do MUTEX
  150. thr2id = -1;//slot thread
  151.  
  152. //Encontra um slot vazio para colocar o arquivo na fila
  153. for(int i = 0; i < TAMANHO_FILA; i++){
  154. if(fila_thr2[i] == NULL){
  155. cout << "Slot "<<i<<" livre."<<endl;
  156.  
  157. //Aloca vetores - Arquivo *
  158. fila_thr2[i] = (Arquivo *)malloc(sizeof(Arquivo *));
  159. thr2id = i;
  160.  
  161. //Adiciona nome do arquivo na estrutura da fila
  162. fila_thr2[i]->set(thr_tmp.nome);
  163. cout << "Arquivo "<< fila_thr2[i]->nome <<" adicionado a fila!" << endl;
  164.  
  165. //Cria thread 2
  166. thr2[i] = CreateThread(NULL,0,runn_thr2,NULL,0,NULL);
  167.  
  168. //Aumenta contagem da fila
  169. fila_count++;
  170.  
  171. break;
  172. }
  173. }
  174. //Valor se encontra 0 pois não foi modificado acima
  175. if(thr2id < 0){
  176. cout << "Nao foi possivel adicionar arquivo "<< thr_tmp.nome <<" a fila."<< endl;
  177. }
  178. }
  179. }
  180. }
  181.  
  182. /* Impressora */
  183. DWORD WINAPI runn_thr2(void *){
  184. int id = thr2id;//Slot do thread
  185. thr2id = 0;//Limpa variavel
  186. int sleeptime = id * DELAYMS_IMPRESSAO;//Delay de impressao
  187.  
  188.  
  189. while(1){
  190. //Imprimir arquivos - so quando receber o sinal do usuario
  191. if(imp_arquivo){
  192.  
  193. // --- Impedir multiuso dos threads 2 - não sobrecarregar a impressora
  194. vblock_imp = CreateSemaphore(NULL,10,10,NULL);
  195.  
  196. if(!wait_thread(vblock_imp)){
  197. while(1){
  198. vblock_imp = CreateSemaphore(NULL,10,10,NULL);
  199. if(wait_thread(vblock_imp))break;
  200. }
  201. }
  202. // ---- ---------------------------------------------------------------
  203.  
  204. Sleep(sleeptime);//Esse tempo impede que um Slot atravesse a vez do outro
  205. cout << "Arquivo "<< fila_thr2[id]->nome <<" imprimido!\n"<<endl;//Output
  206. fila_thr2[id] = NULL;//Esvazia slot da fila
  207. fila_count--;//Aumenta contagem
  208.  
  209. ReleaseSemaphore(vblock_imp,10,NULL);//Desbloqueia Semafaro
  210. imp_arquivo = false;
  211. break;
  212. }
  213. }
  214. }
  215. //Inicia thread 1
  216. void init_threads(){
  217. thr1 = CreateThread(NULL,0,runn_thr1,NULL,0,NULL);//Cria thread 1
  218. }
  219.  
  220. //Funcao que verifica o resultado de um semafaro
  221. //Retorna:
  222. //true -> semafaro verde
  223. //false -> semafaro vermelho
  224. bool wait_thread(HANDLE smp){
  225. DWORD wres = WaitForSingleObject(smp,0L);
  226. switch(wres){
  227. case WAIT_OBJECT_0:
  228. //Continuar thread
  229. return true;
  230. break;
  231. case WAIT_TIMEOUT:
  232. //Thread não pode continuar
  233. return false;
  234. break;
  235. default:
  236. break;
  237. }
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement