Tag: SO2 – 2021 – Ficha 4 v.2.2 – Threads.pdf
sessão 4 – Gestão básica de threads em Win32
Bibliografia de apoio:
Capítulos 6, 7 e 8 do Livro Windows System Programming (da Bibliografia) (pags. 194-195, 223-232, 243-245,252-253, 279-281)
MSDN:
Acerca de threads e processos https://docs.microsoft.com/en-us/windows/win32/procthread/about-processes-and-threads
Gestão de threads https://docs.microsoft.com/en-us/windows/win32/procthread/multiple-threads
Criação de threads (exemplo) https://docs.microsoft.com/en-us/windows/win32/procthread/creating-threads
Funções básicas de espera (WaitforSingleObject / WaitForMultipleObjects) https://docs.microsoft.com/en-us/windows/win32/sync/wait-functions#single-object-waitfunctions
Mutexes https://docs.microsoft.com/en-us/windows/win32/sync/using-mutex-objects
Para criar uma thread:
sabe o que é necessário que seja executado em simultâneo para além da thread principal (e sem interromper a thread principal)
CreateThread( NULL, //segurança: descritores de segurança, só o utilizador é que pode interagir com a thread 0, //tamanho máximo da pilha, cria quantas variáveis locais que ela quiser criar (e só pertencem a ela) FuncaoThread, //nome da função para correr em simultâneo (podemos passar um parâmetro para esta função) &total, //LPVOID parametro, ponteiro para void, uso referencia para poder obter o valor atualizado 0, //eu pretendo que a thread comece a correr, onde 0 é para começar a correr (por oposição de a deixar suspensa, com o resume: CREATE_SUSPENDED) &threadId //opcional: é o threadID, é um DWORD ou colocar NULL se não quiser usar );
//uma unica thread #include <windows.h> #include <tchar.h> #include <io.h> #include <fcntl.h> #include <stdio.h> #define TAM 200 DWORD WINAPI FuncaoThread(LPVOID parametro) { int* dados = (int*)parametro; for (int i = 0; i <= 100; i++) { (*dados) += i; if(i%15== 0) { Sleep(1000); } } return 0; } int _tmain(int argc, TCHAR* argv[]) { DWORD t1; int total = 0; HANDLE hThread; hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) FuncaoThread, &total, 0, &t1); //sleep() //WaitForSingleObject() if(hThread != NULL) { WaitForSingleObject(hThread, INFINITE); //esperar até terminar ou dar um tempo _tprintf(TEXT("resultado da thread: %d"), total); //getchar(); CloseHandle(hThread); }else { _tprintf(TEXT("nada de threads")); } return 0; }
DWORD WaitForMultipleObjects( DWORD nCount, //numero de handles do array const HANDLE *lpHandles, //array de handles BOOL bWaitAll, // true se espero por todas DWORD dwMilliseconds //indicar se espero pelo fim de todas );
#include <windows.h> #include <tchar.h> #include <io.h> #include <fcntl.h> #include <stdio.h> #define TAM 200 #define MAX_THREADS 2 BOOL sairThread = FALSE; typedef struct { int total, limite_inferior, limite_superior; } dados_thread; DWORD WINAPI FuncaoThread(LPVOID parametro) { dados_thread * dados = (dados_thread *) parametro; //ponteiro para a estrutura for (int i = dados->limite_inferior; i <= dados->limite_superior; i++) { dados->total += i; if (i % 15 == 0) { Sleep(1000); if(sairThread) { break; } } } return 0; } DWORD WINAPI comandos(LPVOID parametro) { TCHAR comando[TAM]; while(!sairThread) { _tprintf(TEXT("Escrever 'sair' para terminar.. \n")); wscanf_s(TEXT("%s"),comando, TAM-1); if(wcscmp(comando, TEXT("sair"))==0) { sairThread = TRUE; } } return 0; } int _tmain(int argc, TCHAR* argv[]) { DWORD t1, t2; dados_thread dado[MAX_THREADS]; HANDLE hThreadArray[MAX_THREADS]; //handle threads #ifdef UNICODE _setmode(_fileno(stdin), _O_WTEXT); _setmode(_fileno(stdout), _O_WTEXT); _setmode(_fileno(stderr), _O_WTEXT); #endif dado[0].limite_inferior = 0; dado[0].limite_superior = 100; dado[0].total = 0; dado[1].limite_inferior = 0; dado[1].limite_superior = 100; dado[1].total = 0; hThreadArray[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FuncaoThread, &dado[0], 0, &t1); hThreadArray[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FuncaoThread, &dado[1], 0, &t2); CreateThread(NULL, 0, comandos, NULL, 0, NULL); if (hThreadArray[0] == NULL || hThreadArray[1] == NULL) { _tprintf(TEXT("nada de threads")); ExitProcess(3); } WaitForMultipleObjects(2, hThreadArray, TRUE, INFINITE); _tprintf(TEXT("resultado da thread[%d]: %d\n"), t1, dado[0].total); _tprintf(TEXT("resultado da thread[%d]: %d\n"), t2, dado[1].total); CloseHandle(hThreadArray[0]); CloseHandle(hThreadArray[1]); return 0; }