Advertisement
Guest User

Untitled

a guest
Mar 30th, 2020
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.33 KB | None | 0 0
  1. #include <windows.h>
  2. #include <tchar.h>
  3. #include <math.h>
  4. #include <stdio.h>
  5. #include <fcntl.h>
  6. #include <io.h>
  7.  
  8. // funcionalidade relacionada com temporização
  9. static double PerfCounterFreq; // n ticks por seg.
  10.  
  11. void initClock() {
  12.     LARGE_INTEGER aux;
  13.     if (!QueryPerformanceFrequency(&aux))
  14.         _tprintf(TEXT("\nSorry - No can do em QueryPerfFreq\n"));
  15.     PerfCounterFreq = (double)(aux.QuadPart); // / 1000.0;
  16.     _tprintf(TEXT("\nTicks por sec.%f\n"), PerfCounterFreq);
  17. }
  18.  
  19. __int64 startClock() {
  20.     LARGE_INTEGER aux;
  21.     QueryPerformanceCounter(&aux);
  22.     return aux.QuadPart;
  23. }
  24.  
  25. double stopClock(__int64 from) {
  26.     LARGE_INTEGER aux;
  27.     QueryPerformanceCounter(&aux);
  28.     return (double)(aux.QuadPart - from) / PerfCounterFreq;
  29. }
  30.  
  31. // estrutura de dados para controlar as threads
  32. typedef struct {
  33.     int id;
  34.     int limInf, limSup;
  35.     int Result;
  36.     int* contador;
  37.     CRITICAL_SECTION *criticalSection;
  38. } TDados;
  39.  
  40. // função da(s) thread(s)
  41. DWORD WINAPI ThreadMultiplos3(LPVOID param);
  42. // número * máximo * de threads
  43. // podem (e devem) ser menos
  44.  
  45. #define MAX_THREADS 10
  46.  
  47. int _tmain(int argc, TCHAR* argv[]) {
  48.     HANDLE hThreads[MAX_THREADS]; // matriz de handles das threads
  49.     DWORD threadId[MAX_THREADS];
  50.     TDados tdados[MAX_THREADS]; // Matriz de dados para as threads;
  51.     int numthreads; // número efectivo de threads
  52.     unsigned int limsup; // limite superior
  53.     __int64 clockticks; // variáveis para cronómetro
  54.     double duracao;
  55.     unsigned int range;
  56.     unsigned int inter;
  57.     int contador = 0;
  58.     CRITICAL_SECTION criticalSection;
  59.     int quantosNumerosParaCada = 0;
  60.  
  61. #ifdef UNICODE
  62.     _setmode(_fileno(stdin), _O_WTEXT);
  63.     _setmode(_fileno(stdout), _O_WTEXT);
  64. #endif
  65.  
  66.     initClock();
  67.     _tprintf(TEXT("\nLimite sup. -> "));
  68.     _tscanf_s(TEXT("%u"), &limsup);
  69.     _tprintf(TEXT("\nNum threads -> "));
  70.     _tscanf_s(TEXT("%u"), &numthreads);
  71.     if (numthreads > MAX_THREADS)
  72.         numthreads = MAX_THREADS;
  73.  
  74.     InitializeCriticalSection(&criticalSection);
  75.  
  76.  
  77.     EnterCriticalSection(&criticalSection);
  78.     LeaveCriticalSection(&criticalSection);
  79.  
  80.     quantosNumerosParaCada = limsup / numthreads;
  81.  
  82.     for (int i = 0; i < numthreads; i++) {
  83.         if (i == 0) {
  84.             tdados[i].limSup = quantosNumerosParaCada;
  85.             tdados[i].limInf = 1;
  86.         }
  87.         else {
  88.             tdados[i].limInf = tdados[i - 1].limSup + 1;
  89.             tdados[i].limSup = tdados[i].limInf + quantosNumerosParaCada - 1;
  90.         }
  91.         tdados[i].contador = &contador;
  92.         tdados[i].criticalSection = &criticalSection;
  93.         tdados[i].Result = 0;
  94.     }
  95.  
  96.     // FAZER prepara e cria threads
  97.     for (int i = 0; i < numthreads; i++) {
  98.         hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMultiplos3, (LPVOID)&tdados[i], CREATE_SUSPENDED, &threadId[i]); //CREATE_SUSPENDED para nao comecar logo
  99.  
  100.         if (hThreads[i] != NULL) {
  101.             _tprintf(TEXT("\nLancei uma thread Multiplos3 com id %d\n"), threadId[i]);
  102.             tdados[i].id = threadId[i];
  103.         }
  104.         else
  105.             _tprintf(TEXT("\nErro ao criar Thread\n"));
  106.     }
  107.  
  108.     clockticks = startClock();
  109.  
  110.     // manda as threads começar
  111.     for (int i = 0; i < numthreads; i++)
  112.         ResumeThread(hThreads[i]);              //comeca as threads so aqui
  113.  
  114.  
  115.     // FAZER aguarda / controla as threads
  116.     // manda as threads parar
  117.     HANDLE ghEvents[MAX_THREADS];
  118.     for (int i = 0; i < numthreads; i++)
  119.         ghEvents[i] = hThreads[i];
  120.     WaitForMultipleObjects(numthreads, ghEvents, TRUE, INFINITE);
  121.  
  122.  
  123.     duracao = stopClock(clockticks);
  124.     _tprintf(TEXT("\nSegundos=%f\n"), duracao);
  125.  
  126.     // FAZER apresenta resultados
  127.     _tprintf(TEXT("Resultado do contador de Multiplos de 3: %d \n"), *tdados[0].contador);
  128.  
  129.     DeleteCriticalSection(&criticalSection);
  130.  
  131.     // Cód. ref. para aguardar por uma tecla – caso faça falta
  132.     // _tprintf(TEXT("\nCarregue numa tecla"));
  133.     // _gettch();
  134.     return 0;
  135. }
  136.  
  137. DWORD WINAPI ThreadMultiplos3(LPVOID param) {    //começa sempre por DWORD WINAPI e recebe sempre um LPVOID
  138.     int i, contador = 0;
  139.     TDados* y = ((TDados*)param);
  140.     _tprintf(TEXT("[Thread %d]Vou começar a trabalhar (%d - %d)\n"), GetCurrentThreadId(), y->limInf, y->limSup);
  141.     Sleep(100);
  142.  
  143.     for (i = y->limInf; i <= y->limSup; i++) {
  144.         if (i > 0 && i % 3 == 0) {
  145.             y->Result = y->Result + i;
  146.             contador++;
  147.             _tprintf(TEXT(" %d é multiplo de 3. \n"), i);
  148.             if (contador > 0 && contador % 200 == 0) {
  149.                 Sleep(1000);
  150.             }
  151.             EnterCriticalSection(y->criticalSection);
  152.             (*(y->contador))++;
  153.             LeaveCriticalSection(y->criticalSection);
  154.         }
  155.     }
  156.  
  157.     ExitThread(0);
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement