Public feed
#601673
#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0501#endif#include <Windows.h>#include <process.h>#include <cstdio>#include <ctime>#include <iostream>#define MAX_THREADS 3#define MUTEX_INIT_ERROR 1#define MUTEX_LOCK_ERROR 2#define THREAD_CREATION_ERROR 4#define THREAD_START_ERROR 8using namespace std;unsigned WINAPI workThread0(void *);int init_Mutex(void);void create_wThreads(HANDLE *, unsigned *);void start_wThreads(HANDLE *, unsigned *);void clrscr(void);void gotoxy(int, int);HANDLE screenMutex;HANDLE syncPoint;HANDLE workMutex;bool volatile workDone;int volatile threadIndex = 0;intmain(void){ HANDLE thRet[MAX_THREADS]; unsigned lpThreadId[MAX_THREADS]; DWORD dwWaitResult; int syncTh = 0; int i, tmp; clrscr(); cout << "Master thread started.\n"; workDone = false; srand ((unsigned int) time(NULL)); cout << "Initializing mutexes..."; tmp = init_Mutex(); if(tmp) { return tmp; } cout << " done.\n"; cout << "Creating working threads..."; create_wThreads(thRet, lpThreadId); cout << " done.\n\n"; for (i = 0; i < MAX_THREADS; ++i) cout << "Thread " << i << " has ID: " << lpThreadId[i] << "\n"; cout << "\nStarting threads... (Press RETURN to stop)\n\n"; start_wThreads(thRet, lpThreadId); dwWaitResult = WaitForSingleObject(syncPoint, INFINITE); if (WAIT_OBJECT_0 == dwWaitResult) { syncTh++; if (syncTh == MAX_THREADS) SetEvent(workMutex); } else if (WAIT_TIMEOUT == dwWaitResult) { cout << "Error accessing critical section: " << GetLastError() << "\n"; return MUTEX_LOCK_ERROR; } getchar(); workDone = true; WaitForMultipleObjects(MAX_THREADS, thRet, TRUE, INFINITE); for(i = 0; i < MAX_THREADS; ++i) { CloseHandle(thRet[i]); } CloseHandle(screenMutex); return 0;}unsigned int WINAPIworkThread0(void *lpParameter){ int thNum; DWORD dwWaitResult; int i = 0; dwWaitResult = WaitForSingleObject( screenMutex, INFINITE); if (dwWaitResult == WAIT_TIMEOUT) { cout << "Error accessing critical section: " << GetLastError() << "\n"; return MUTEX_LOCK_ERROR; } thNum = ++threadIndex; cout << "This is thread number " << thNum << ".\n"; ReleaseMutex(screenMutex); dwWaitResult = SignalObjectAndWait( syncPoint, workMutex, INFINITE, FALSE); if (dwWaitResult == WAIT_TIMEOUT) { cout << "Error accessing critical section: " << GetLastError() << "\n"; return MUTEX_LOCK_ERROR; } while (!workDone) { ++i; dwWaitResult = WaitForSingleObject( screenMutex, INFINITE); if (dwWaitResult == WAIT_TIMEOUT) { cout << "Error accessing critical section: " << GetLastError() << "\n"; return MUTEX_LOCK_ERROR; } cout << "(" << thNum << ", " << i << ") "; ReleaseMutex(screenMutex); Sleep(rand() % 1000); } return 0;}intinit_Mutex(void){ screenMutex = CreateMutex( NULL, false, // mutex is unlocked NULL); if (screenMutex == NULL) { cout << "CreateMutex error: " << GetLastError() << "\n"; return MUTEX_INIT_ERROR; } workMutex = CreateMutex( NULL, true, // main thread holds ownership NULL); if (workMutex == NULL) { cout << "CreateMutex error: " << GetLastError() << "\n"; return MUTEX_INIT_ERROR; } return 0;}voidcreate_wThreads(HANDLE *thRet, unsigned *lpThreadId){ int i; for (i = 0; i < MAX_THREADS; ++i) { thRet[i] = (HANDLE) _beginthreadex( NULL, 0, workThread0, NULL, CREATE_SUSPENDED, &lpThreadId[i]); if (thRet[i] == 0) { cout << "\nError creating thread: " \ << GetLastError() << "\n"; ExitProcess(THREAD_CREATION_ERROR); } }}void start_wThreads(HANDLE *thRet, unsigned *lpThreadId){ int i; for (i = 0; i < MAX_THREADS; ++i) { int resRet; resRet = ResumeThread(thRet[i]); if (resRet == -1) { cout << "Thread " << lpThreadId[i] << " could not be started: " << GetLastError() << "\n"; ExitProcess(THREAD_START_ERROR); } }}voidclrscr(void){ CONSOLE_SCREEN_BUFFER_INFO csbiInfo; HANDLE hConsoleOut; COORD Home = {0,0}; DWORD dummy; hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo); FillConsoleOutputCharacter(hConsoleOut,' ', csbiInfo.dwSize.X * csbiInfo.dwSize.Y, Home, &dummy); csbiInfo.dwCursorPosition.X = 0; csbiInfo.dwCursorPosition.Y = 0; SetConsoleCursorPosition(hConsoleOut, csbiInfo.dwCursorPosition);}void gotoxy(int x, int y){ CONSOLE_SCREEN_BUFFER_INFO csbiInfo; HANDLE hConsoleOut; hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo); csbiInfo.dwCursorPosition.X = x; csbiInfo.dwCursorPosition.Y = y; SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);}