Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Windows.h>
- #include <stdio.h>
- #include "stdlib.h"
- #include <tchar.h>
- #include <string.h>
- #include "resource.h"
- #include <time.h>
- #include <process.h>
- LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM);
- void InitThreadFunc(void *v); // поток для инициализации элементов массива
- void WriteThreadFunc(void *v); // поток для вывода элементов массива
- void SortThreadFunc(void *v); // поток для сортировки элементов массива
- DWORD WINAPI Func(int); // функция-обработчик нажатия кнопок запуска потоков
- DWORD WINAPI Func_Sync_Init(int); // переход элементов синхронизации в режим ожидания
- DWORD WINAPI Func_Sync_Clear(int); // очистка элементов синхронизации
- HWND hwnd1; // переменная рабочего окна
- HINSTANCE hInst;
- int *matrix,size,t;
- char *buf; // указатель на строку, выводящую элементы массива
- HANDLE mutex; // переменная мьютекса
- CRITICAL_SECTION cs; // переменная критической секции
- HANDLE semaphore; // переменая семафора
- HANDLE event1,event2,event3; // переменные ивентов
- bool b1=false,b2=false,b3=false,b4=false, // переменные, показывающие, какой поток был запущен
- process=true; // переменная, участвующая в управлении потоками
- HANDLE hInit,hWrite,hSort; // хэндлы потоков
- BOOL lpTranslated;
- int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
- {
- MSG msg; // переменная сообщения
- WNDCLASSEX MainWindow; // класс окна
- MainWindow.cbSize = sizeof(MainWindow);
- MainWindow.style = CS_HREDRAW | CS_VREDRAW ;
- MainWindow.lpfnWndProc = MainWndProc;
- MainWindow.cbClsExtra = 0;
- MainWindow.cbWndExtra = 0;
- MainWindow.hInstance = hInstance;
- MainWindow.hIcon = LoadIcon(hInstance, NULL);
- MainWindow.hCursor = LoadCursor(NULL, IDC_ARROW);
- MainWindow.hbrBackground = CreateSolidBrush(RGB(217,214,254));
- MainWindow.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
- MainWindow.lpszClassName = (LPSTR)"MainWindow";
- MainWindow.hIconSm = LoadIcon(NULL, IDI_ASTERISK);
- RegisterClassEx(&MainWindow);
- hwnd1 = CreateWindow((LPSTR)"MainWindow", // имя оконного класса
- (LPSTR)"Лабораторная работа №7. Синхронизация", // заголовок окна
- WS_OVERLAPPEDWINDOW, // стиль окна
- 350,120, // координаты верхнего левого угла окна
- 870,430, // ширина и высота
- NULL, // описатель окна родительского класса
- NULL, // описатель меню
- hInstance, // описатель приложения
- NULL); // указатель на структуру, которая использует при инициализации экземпляра класса
- ShowWindow (hwnd1,nCmdShow) ; // выводит окно на экран
- UpdateWindow (hwnd1) ; // заставляет окно перерисовывать своё содержимое
- InvalidateRect(hwnd1, NULL, true); // перерисовка окна
- if (!hwnd1)
- {
- MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL);
- return 1;
- }
- BOOL bRet;
- while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
- {
- if (bRet == -1) {
- return false;
- }
- else {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return msg.wParam ;
- }
- LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
- switch (message)
- {
- case WM_CREATE:
- {
- HWND hwndB; // переменная для создания элементов управления на главном окне
- hInst =((LPCREATESTRUCT) lParam)->hInstance;
- // статическое создание элементов управления на главном окне
- hwndB = CreateWindow("STATIC","Введите размерность массива",WS_CHILD|WS_VISIBLE|WS_BORDER,10,10,230,20, hWnd,(HMENU)IDC_STATIC1, hInst, NULL);
- hwndB = CreateWindow("EDIT","5",WS_CHILD|WS_VISIBLE|WS_BORDER,10,40,110,20, hWnd,(HMENU)IDC_EDIT1, hInst, NULL);
- hwndB = CreateWindow("STATIC","Использование мьютексов",WS_CHILD|WS_VISIBLE|WS_BORDER,10,80,200,20, hWnd,(HMENU)IDC_STATIC2, hInst, NULL);
- hwndB = CreateWindow("LISTBOX",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|WS_HSCROLL,10,100,200,200, hWnd,(HMENU)IDC_EDIT2, hInst, NULL);
- hwndB = CreateWindow("BUTTON","СТАРТ / ПАУЗА",WS_CHILD | WS_VISIBLE,10,305,200,20, hWnd, (HMENU)IDC_BUTTON2, hInst, NULL);
- hwndB = CreateWindow("STATIC","Использование крит.секций",WS_CHILD|WS_VISIBLE|WS_BORDER,220,80,200,20, hWnd,(HMENU)IDC_STATIC3, hInst, NULL);
- hwndB = CreateWindow("LISTBOX",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL,220,100,200,200, hWnd,(HMENU)IDC_EDIT3, hInst, NULL);
- hwndB = CreateWindow("BUTTON","СТАРТ / ПАУЗА",WS_CHILD | WS_VISIBLE,220,305,200,20, hWnd, (HMENU)IDC_BUTTON3, hInst, NULL);
- hwndB = CreateWindow("STATIC","Использование ивентов",WS_CHILD|WS_VISIBLE|WS_BORDER,430,80,200,20, hWnd,(HMENU)IDC_STATIC4, hInst, NULL);
- hwndB = CreateWindow("LISTBOX",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL,430,100,200,200, hWnd,(HMENU)IDC_EDIT4,hInst, NULL);
- hwndB = CreateWindow("BUTTON","СТАРТ / ПАУЗА",WS_CHILD | WS_VISIBLE,430,305,200,20, hWnd, (HMENU)IDC_BUTTON4, hInst, NULL);
- hwndB = CreateWindow("STATIC","Использование семафоров",WS_CHILD|WS_VISIBLE|WS_BORDER,640,80,200,20, hWnd,(HMENU)IDC_STATIC5, hInst, NULL);
- hwndB = CreateWindow("LISTBOX",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL,640,100,200,200, hWnd,(HMENU)IDC_EDIT5,hInst, NULL);
- hwndB = CreateWindow("BUTTON","СТАРТ / ПАУЗА",WS_CHILD | WS_VISIBLE,640,305,200,20, hWnd, (HMENU)IDC_BUTTON5, hInst, NULL);
- hwndB = CreateWindow("BUTTON","Выход",WS_CHILD | WS_VISIBLE,740,335,100,20, hWnd, (HMENU)IDC_EXIT, hInst, NULL);
- matrix = new int [size];
- buf = new char[size*2+size];
- size = GetDlgItemInt(hWnd,IDC_EDIT1,&lpTranslated,FALSE);
- break;
- }
- case WM_PAINT:
- hdc = BeginPaint(hWnd, &ps);
- EndPaint(hWnd, &ps);
- return 0;
- case WM_COMMAND:
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- switch (wmId)
- {
- case VK_ESCAPE:
- DestroyWindow(hWnd);
- break;
- case IDC_EXIT:
- PostQuitMessage(0);
- return 0;
- case IDC_BUTTON2: // обработчик нажатия клавиши запуска 1-го потока
- {
- Func(1);
- return 0;
- }
- case IDC_BUTTON3: // обработчик нажатия клавиши запуска 2-го потока
- {
- Func(2);
- return 0;
- }
- case IDC_BUTTON4: // обработчик нажатия клавиши запуска 3-го потока
- {
- Func(3);
- return 0;
- }
- case IDC_BUTTON5: // обработчик нажатия клавиши запуска 4-го потока
- {
- Func(4);
- return 0;
- }
- case ID_40001:
- PostQuitMessage(0);
- return 0;
- case ID_40002:
- MessageBox(hwnd1,"Лабораторная работа №7\nВыполнила: ст.группы 107219\nЗавистовская Е.С.","О программе",NULL);
- return 0;
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- default : return DefWindowProc(hWnd, message, wParam, lParam);
- }
- }
- // функция обработки нажатия кнопок запуска потоков
- DWORD WINAPI Func(int type)
- {
- int temp;
- bool *pbutton; // указатель на переменную, отвечающую за запуск потоков
- size = GetDlgItemInt(hwnd1,IDC_EDIT1,&lpTranslated,FALSE); // считывание элементов массива из Edit
- matrix = new int [size]; // создание динамического массива чисел
- for (int i = 0; i<size; i++)
- matrix[i] = rand()%99+1;
- t = type;
- switch (type)
- {
- case 1:
- pbutton = &b1;
- break;
- case 2:
- pbutton = &b2;
- break;
- case 3:
- pbutton = &b3;
- break;
- case 4:
- pbutton = &b4;
- break;
- }
- if ((temp = GetDlgItemInt(hwnd1,IDC_EDIT1,&lpTranslated,FALSE)) > 2) // кол-во элементов массива
- { // должно быть больше 2
- if (*pbutton == true) // если поток запущен,
- { // он закрывается
- process = false;
- *pbutton = false;
- Sleep(100);
- switch (type) // проверяется, какая клавища была нажата
- { // чтобы определить, что завершать
- case 1:
- CloseHandle(mutex);
- break;
- case 2:
- DeleteCriticalSection(&cs);
- break;
- case 3:
- CloseHandle(event1);
- CloseHandle(event2);
- CloseHandle(event3);
- break;
- case 4:
- CloseHandle(semaphore);
- break;
- }
- //delete matrix;
- //delete buf;
- }
- else // иначе запускается новый поток
- {
- switch (type)
- {
- case 1:
- mutex = CreateMutex(NULL,FALSE,NULL);
- break;
- case 2:
- InitializeCriticalSection(&cs);
- break;
- case 3:
- event1 = CreateEvent(NULL,FALSE,TRUE,NULL);
- event2 = CreateEvent(NULL,FALSE,TRUE,NULL);
- event3 = CreateEvent(NULL,FALSE,TRUE,NULL);
- break;
- case 4:
- semaphore = CreateSemaphore(NULL,1,1,NULL);
- break;
- }
- size = GetDlgItemInt(hwnd1,IDC_EDIT1,&lpTranslated,FALSE);
- hInit = (HANDLE)_beginthread(InitThreadFunc,0,NULL); // запуск потока инициализации массива
- hSort = (HANDLE)_beginthread(SortThreadFunc,0,NULL); // запуск потока сортировки элементов массива
- hWrite = (HANDLE)_beginthread(WriteThreadFunc,0,NULL); // запуск потока вывода элементов массива на экран
- /*hInit = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)InitThreadFunc,NULL, 0, NULL);
- hSort = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)SortThreadFunc,NULL, 0, NULL);
- hWrite = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)WriteThreadFunc,NULL, 0, NULL);*/
- *pbutton = true;
- process = true;
- }
- }
- else
- MessageBox(hwnd1,"Размерность массива задана неверно!","Warning",NULL);
- return 0;
- }
- // переход элементов синхронизации в режим ожидания
- DWORD WINAPI Func_Sync_Init(int temp)
- {
- switch (temp)
- {
- case 1:
- WaitForSingleObject(mutex,INFINITE);
- break;
- case 2:
- EnterCriticalSection(&cs);
- break;
- case 4:
- WaitForSingleObject(semaphore,INFINITE);
- break;
- }
- return 0;
- }
- // очистка элементов синхронизации
- DWORD WINAPI Func_Sync_Clear(int temp)
- {
- switch (temp)
- {
- case 1:
- ReleaseMutex(mutex);
- break;
- case 2:
- LeaveCriticalSection(&cs);
- break;
- case 4:
- ReleaseSemaphore(semaphore,1,NULL);
- break;
- }
- return 0;
- }
- // поток инициализации массива
- void InitThreadFunc(void *v)
- {
- while (process)
- {
- Func_Sync_Init(t);
- if ( t == 3)
- {
- WaitForSingleObject(event3,INFINITE);
- }
- for (int i = 0; i < size; i++) // задание элементов массива рандомными числами
- matrix[i] = rand()%99+1; // в интервале от 1 до 99
- Func_Sync_Clear(t);
- if ( t == 3)
- {
- SetEvent(event1);
- }
- }
- }
- // поток вывода элементов массива в ListBox
- void WriteThreadFunc(void *v)
- {
- int k;
- while (process)
- {
- Func_Sync_Init(t);
- if ( t == 3)
- {
- WaitForSingleObject(event1,INFINITE);
- }
- buf = new char[size*2+size]; // создание динамического массива символов,
- int k = 0; // которые будут содержать числа из массива
- for (int i = 0; i < size; i++)
- k += sprintf(buf+k," %d",matrix[i]);
- k += sprintf(buf+k,"\r\n");
- HWND hTemp;
- switch (t) // определение того, в какой элемент выводить массив
- { // по переменной, запоминающей номер нажатой клавиши
- case 1:
- hTemp = GetDlgItem(hwnd1,IDC_EDIT2);
- break;
- case 2:
- hTemp = GetDlgItem(hwnd1,IDC_EDIT3);
- break;
- case 3:
- hTemp = GetDlgItem(hwnd1,IDC_EDIT4);
- break;
- case 4:
- hTemp = GetDlgItem(hwnd1,IDC_EDIT5);
- break;
- }
- SendMessageA(hTemp,LB_ADDSTRING,NULL,(LPARAM)buf); // непосредственный вывод в ListBox
- Sleep(200);
- Func_Sync_Clear(t);
- if ( t == 3)
- {
- SetEvent(event2);
- }
- }
- }
- // поток сортировки элементов массива в порядке возрастания
- void SortThreadFunc(void *v)
- {
- int temp,k;
- while (process)
- {
- Func_Sync_Init(t);
- if ( t == 3)
- {
- WaitForSingleObject(event2,INFINITE);
- }
- for (int i = 1; i < size; i++) // сортировка массива
- for (int j = 0; j < size-1; j++) // методом пузырька
- if (matrix[i]<matrix[j])
- {
- temp = matrix[i];
- matrix[i] = matrix[j];
- matrix[j] = temp;
- }
- Func_Sync_Clear(t);
- if ( t == 3)
- {
- SetEvent(event3);
- }
- }
- }
Add Comment
Please, Sign In to add comment