Guest User

Untitled

a guest
Apr 26th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.78 KB | None | 0 0
  1. #include <Windows.h>
  2. #include <stdio.h>
  3. #include "stdlib.h"
  4. #include <tchar.h>
  5. #include <string.h>
  6. #include "resource.h"
  7. #include <time.h>
  8. #include <process.h>
  9.  
  10. LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM); 
  11. void InitThreadFunc(void *v);       // поток для инициализации элементов массива
  12. void WriteThreadFunc(void *v);      // поток для вывода элементов массива
  13. void SortThreadFunc(void *v);       // поток для сортировки элементов массива
  14. DWORD WINAPI Func(int);             // функция-обработчик нажатия кнопок запуска потоков
  15. DWORD WINAPI Func_Sync_Init(int);   // переход элементов синхронизации в режим ожидания
  16. DWORD WINAPI Func_Sync_Clear(int);  // очистка элементов синхронизации
  17.  
  18. HWND hwnd1;         // переменная рабочего окна
  19. HINSTANCE hInst;
  20.  
  21. int *matrix,size,t;
  22. char *buf;          // указатель на строку, выводящую элементы массива
  23.  
  24. HANDLE mutex;           // переменная мьютекса
  25. CRITICAL_SECTION cs;    // переменная критической секции
  26. HANDLE semaphore;       // переменая семафора
  27. HANDLE event1,event2,event3;    // переменные ивентов
  28.  
  29. bool b1=false,b2=false,b3=false,b4=false,   // переменные, показывающие, какой поток был запущен
  30.     process=true;       // переменная, участвующая в управлении потоками
  31. HANDLE hInit,hWrite,hSort;  // хэндлы потоков
  32. BOOL lpTranslated;
  33.  
  34. int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
  35. {  
  36.     MSG msg;            // переменная сообщения
  37.    
  38.     WNDCLASSEX MainWindow;  // класс окна
  39.  
  40.     MainWindow.cbSize           = sizeof(MainWindow);
  41.     MainWindow.style            = CS_HREDRAW | CS_VREDRAW ;
  42.     MainWindow.lpfnWndProc  = MainWndProc;
  43.     MainWindow.cbClsExtra       = 0;
  44.     MainWindow.cbWndExtra       = 0;
  45.     MainWindow.hInstance        = hInstance;
  46.     MainWindow.hIcon = LoadIcon(hInstance, NULL);
  47.     MainWindow.hCursor      = LoadCursor(NULL, IDC_ARROW);
  48.     MainWindow.hbrBackground    = CreateSolidBrush(RGB(217,214,254));
  49.     MainWindow.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
  50.     MainWindow.lpszClassName    = (LPSTR)"MainWindow";
  51.     MainWindow.hIconSm      = LoadIcon(NULL, IDI_ASTERISK);
  52.     RegisterClassEx(&MainWindow);
  53.  
  54.     hwnd1 = CreateWindow((LPSTR)"MainWindow",   // имя оконного класса
  55.                          (LPSTR)"Лабораторная работа №7. Синхронизация",   // заголовок окна
  56.                          WS_OVERLAPPEDWINDOW,   // стиль окна
  57.                          350,120,     // координаты верхнего левого угла окна
  58.                          870,430,       // ширина и высота
  59.                          NULL,          // описатель окна родительского класса
  60.                          NULL,          // описатель меню
  61.                          hInstance,     // описатель приложения
  62.                          NULL);         // указатель на структуру, которая использует при инициализации экземпляра класса
  63.  
  64.     ShowWindow (hwnd1,nCmdShow) ;       // выводит окно на экран
  65.     UpdateWindow (hwnd1) ;              // заставляет окно перерисовывать своё содержимое
  66.     InvalidateRect(hwnd1, NULL, true);  // перерисовка окна
  67.    
  68.     if (!hwnd1)
  69.     {
  70.         MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL);
  71.         return 1;
  72.     }
  73.  
  74.     BOOL bRet;
  75.     while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
  76.     {
  77.         if (bRet == -1) {
  78.              return false;
  79.         }
  80.         else {
  81.             TranslateMessage(&msg);
  82.             DispatchMessage(&msg);  
  83.         }
  84.     }  
  85.     return msg.wParam ;
  86. }
  87.  
  88. LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  89. {
  90.     int wmId, wmEvent;
  91.     PAINTSTRUCT ps;
  92.     HDC hdc;
  93.  
  94.     switch (message)
  95.     {
  96.     case WM_CREATE:
  97.         {
  98.             HWND hwndB; // переменная для создания элементов управления на главном окне
  99.             hInst =((LPCREATESTRUCT) lParam)->hInstance;
  100.             // статическое создание элементов управления на главном окне
  101.             hwndB = CreateWindow("STATIC","Введите размерность массива",WS_CHILD|WS_VISIBLE|WS_BORDER,10,10,230,20, hWnd,(HMENU)IDC_STATIC1, hInst, NULL);
  102.             hwndB = CreateWindow("EDIT","5",WS_CHILD|WS_VISIBLE|WS_BORDER,10,40,110,20, hWnd,(HMENU)IDC_EDIT1, hInst, NULL);
  103.             hwndB = CreateWindow("STATIC","Использование мьютексов",WS_CHILD|WS_VISIBLE|WS_BORDER,10,80,200,20, hWnd,(HMENU)IDC_STATIC2, hInst, NULL);
  104.             hwndB = CreateWindow("LISTBOX",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|WS_HSCROLL,10,100,200,200, hWnd,(HMENU)IDC_EDIT2, hInst, NULL);
  105.             hwndB = CreateWindow("BUTTON","СТАРТ / ПАУЗА",WS_CHILD | WS_VISIBLE,10,305,200,20, hWnd, (HMENU)IDC_BUTTON2, hInst, NULL);
  106.             hwndB = CreateWindow("STATIC","Использование крит.секций",WS_CHILD|WS_VISIBLE|WS_BORDER,220,80,200,20, hWnd,(HMENU)IDC_STATIC3, hInst, NULL);
  107.             hwndB = CreateWindow("LISTBOX",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL,220,100,200,200, hWnd,(HMENU)IDC_EDIT3, hInst, NULL);
  108.             hwndB = CreateWindow("BUTTON","СТАРТ / ПАУЗА",WS_CHILD | WS_VISIBLE,220,305,200,20, hWnd, (HMENU)IDC_BUTTON3, hInst, NULL);
  109.             hwndB = CreateWindow("STATIC","Использование ивентов",WS_CHILD|WS_VISIBLE|WS_BORDER,430,80,200,20, hWnd,(HMENU)IDC_STATIC4, hInst, NULL);
  110.             hwndB = CreateWindow("LISTBOX",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL,430,100,200,200, hWnd,(HMENU)IDC_EDIT4,hInst, NULL);
  111.             hwndB = CreateWindow("BUTTON","СТАРТ / ПАУЗА",WS_CHILD | WS_VISIBLE,430,305,200,20, hWnd, (HMENU)IDC_BUTTON4, hInst, NULL);
  112.             hwndB = CreateWindow("STATIC","Использование семафоров",WS_CHILD|WS_VISIBLE|WS_BORDER,640,80,200,20, hWnd,(HMENU)IDC_STATIC5, hInst, NULL);
  113.             hwndB = CreateWindow("LISTBOX",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL,640,100,200,200, hWnd,(HMENU)IDC_EDIT5,hInst, NULL);
  114.             hwndB = CreateWindow("BUTTON","СТАРТ / ПАУЗА",WS_CHILD | WS_VISIBLE,640,305,200,20, hWnd, (HMENU)IDC_BUTTON5, hInst, NULL);
  115.             hwndB = CreateWindow("BUTTON","Выход",WS_CHILD | WS_VISIBLE,740,335,100,20, hWnd, (HMENU)IDC_EXIT, hInst, NULL);
  116.  
  117.             matrix = new int [size];
  118.             buf = new char[size*2+size];
  119.             size = GetDlgItemInt(hWnd,IDC_EDIT1,&lpTranslated,FALSE);
  120.  
  121.             break;
  122.         }
  123.  
  124.     case WM_PAINT:
  125.         hdc = BeginPaint(hWnd, &ps);
  126.         EndPaint(hWnd, &ps);
  127.         return 0;
  128.     case WM_COMMAND:
  129.         wmId    = LOWORD(wParam);
  130.         wmEvent = HIWORD(wParam);
  131.         switch (wmId)
  132.         {
  133.         case VK_ESCAPE:
  134.             DestroyWindow(hWnd);
  135.             break;
  136.  
  137.         case IDC_EXIT:
  138.             PostQuitMessage(0);
  139.             return 0;
  140.  
  141.         case IDC_BUTTON2: // обработчик нажатия клавиши запуска 1-го потока
  142.         {
  143.             Func(1);
  144.             return 0;
  145.         }
  146.  
  147.         case IDC_BUTTON3: // обработчик нажатия клавиши запуска 2-го потока
  148.         {
  149.             Func(2);
  150.             return 0;
  151.         }
  152.  
  153.         case IDC_BUTTON4: // обработчик нажатия клавиши запуска 3-го потока
  154.         {
  155.             Func(3);
  156.             return 0;
  157.         }
  158.  
  159.         case IDC_BUTTON5: // обработчик нажатия клавиши запуска 4-го потока
  160.         {
  161.             Func(4);
  162.             return 0;
  163.         }
  164.  
  165.         case ID_40001:
  166.             PostQuitMessage(0);
  167.             return 0;
  168.         case ID_40002:
  169.             MessageBox(hwnd1,"Лабораторная работа №7\nВыполнила: ст.группы 107219\nЗавистовская Е.С.","О программе",NULL);
  170.             return 0;
  171.         break;
  172.     case WM_DESTROY:
  173.         PostQuitMessage(0);
  174.         return 0;  
  175.     }
  176.     default : return DefWindowProc(hWnd, message, wParam, lParam);
  177.     }
  178. }
  179.  
  180. // функция обработки нажатия кнопок запуска потоков
  181. DWORD WINAPI Func(int type)
  182. {
  183.     int temp;
  184.     bool *pbutton;      // указатель на переменную, отвечающую за запуск потоков
  185.  
  186.     size = GetDlgItemInt(hwnd1,IDC_EDIT1,&lpTranslated,FALSE);  // считывание элементов массива из Edit
  187.     matrix = new int [size];    // создание динамического массива чисел
  188.     for (int i = 0; i<size; i++)
  189.         matrix[i] = rand()%99+1;
  190.     t = type;
  191.  
  192.     switch (type)      
  193.     {
  194.     case 1:
  195.         pbutton = &b1;
  196.         break;
  197.     case 2:
  198.         pbutton = &b2;
  199.         break;
  200.     case 3:
  201.         pbutton = &b3;
  202.         break;
  203.     case 4:
  204.         pbutton = &b4;
  205.         break;
  206.     }
  207.  
  208.     if ((temp = GetDlgItemInt(hwnd1,IDC_EDIT1,&lpTranslated,FALSE)) > 2) // кол-во элементов массива
  209.     {                                                                    // должно быть больше 2
  210.         if (*pbutton == true)       // если поток запущен,
  211.         {                           // он закрывается
  212.             process = false;
  213.             *pbutton = false;
  214.             Sleep(100);
  215.  
  216.             switch (type)           // проверяется, какая клавища была нажата
  217.             {                       // чтобы определить, что завершать
  218.             case 1:
  219.                 CloseHandle(mutex);
  220.                 break;
  221.             case 2:
  222.                 DeleteCriticalSection(&cs);
  223.                 break;
  224.             case 3:
  225.                 CloseHandle(event1);
  226.                 CloseHandle(event2);
  227.                 CloseHandle(event3);
  228.                 break;
  229.             case 4:
  230.                 CloseHandle(semaphore);
  231.                 break;
  232.             }  
  233.             //delete matrix;
  234.             //delete  buf;
  235.         }
  236.         else    // иначе запускается новый поток
  237.         {
  238.             switch (type)
  239.             {
  240.             case 1:
  241.                 mutex = CreateMutex(NULL,FALSE,NULL);
  242.                 break;
  243.             case 2:
  244.                 InitializeCriticalSection(&cs);
  245.                 break;
  246.             case 3:
  247.                 event1 = CreateEvent(NULL,FALSE,TRUE,NULL);
  248.                 event2 = CreateEvent(NULL,FALSE,TRUE,NULL);
  249.                 event3 = CreateEvent(NULL,FALSE,TRUE,NULL);
  250.                 break;
  251.             case 4:
  252.                 semaphore = CreateSemaphore(NULL,1,1,NULL);
  253.                 break;
  254.             }  
  255.                    
  256.             size = GetDlgItemInt(hwnd1,IDC_EDIT1,&lpTranslated,FALSE);
  257.  
  258.             hInit = (HANDLE)_beginthread(InitThreadFunc,0,NULL);    // запуск потока инициализации массива
  259.             hSort = (HANDLE)_beginthread(SortThreadFunc,0,NULL);    // запуск потока сортировки элементов массива
  260.             hWrite = (HANDLE)_beginthread(WriteThreadFunc,0,NULL);  // запуск потока вывода элементов массива на экран
  261.            
  262.             /*hInit = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)InitThreadFunc,NULL, 0, NULL);
  263.             hSort = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)SortThreadFunc,NULL, 0, NULL);
  264.             hWrite = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)WriteThreadFunc,NULL, 0, NULL);*/
  265.  
  266.             *pbutton = true;
  267.             process = true;
  268.         }
  269.     }
  270.     else
  271.         MessageBox(hwnd1,"Размерность массива задана неверно!","Warning",NULL);
  272.  
  273.     return 0;
  274. }
  275.  
  276. // переход элементов синхронизации в режим ожидания
  277. DWORD WINAPI Func_Sync_Init(int temp)
  278. {
  279.     switch (temp)
  280.     {
  281.     case 1:
  282.         WaitForSingleObject(mutex,INFINITE);
  283.         break;
  284.     case 2:
  285.         EnterCriticalSection(&cs);
  286.         break;
  287.     case 4:
  288.         WaitForSingleObject(semaphore,INFINITE);
  289.         break;
  290.     }
  291.  
  292.     return 0;
  293. }
  294.  
  295. // очистка элементов синхронизации
  296. DWORD WINAPI Func_Sync_Clear(int temp)
  297. {
  298.     switch (temp)
  299.     {
  300.     case 1:
  301.         ReleaseMutex(mutex);
  302.         break;
  303.     case 2:
  304.         LeaveCriticalSection(&cs);
  305.         break;
  306.     case 4:
  307.         ReleaseSemaphore(semaphore,1,NULL);
  308.         break;
  309.     }  
  310.  
  311.     return 0;
  312. }
  313.  
  314. // поток инициализации массива
  315. void InitThreadFunc(void *v)
  316. {
  317.     while (process)
  318.     {
  319.         Func_Sync_Init(t);
  320.         if ( t == 3)
  321.         {
  322.             WaitForSingleObject(event3,INFINITE);
  323.         }
  324.  
  325.         for (int i = 0; i < size; i++)  // задание элементов массива рандомными числами
  326.             matrix[i] = rand()%99+1;    // в интервале от 1 до 99
  327.        
  328.         Func_Sync_Clear(t);
  329.         if ( t == 3)
  330.         {
  331.             SetEvent(event1);
  332.         }
  333.     }
  334. }
  335.  
  336. // поток вывода элементов массива в ListBox
  337. void WriteThreadFunc(void *v)
  338. {
  339.     int k;
  340.     while (process)
  341.     {
  342.         Func_Sync_Init(t);
  343.         if ( t == 3)
  344.         {
  345.             WaitForSingleObject(event1,INFINITE);
  346.         }
  347.  
  348.         buf = new char[size*2+size];    // создание динамического массива символов,
  349.         int k = 0;                      // которые будут содержать числа из массива
  350.  
  351.         for (int i = 0; i < size; i++)
  352.             k += sprintf(buf+k," %d",matrix[i]);
  353.         k += sprintf(buf+k,"\r\n");
  354.        
  355.         HWND hTemp;
  356.         switch (t)                      // определение того, в какой элемент выводить массив
  357.         {                               // по переменной, запоминающей номер нажатой клавиши
  358.         case 1:
  359.             hTemp = GetDlgItem(hwnd1,IDC_EDIT2);
  360.             break;
  361.         case 2:
  362.             hTemp = GetDlgItem(hwnd1,IDC_EDIT3);
  363.             break;
  364.         case 3:
  365.             hTemp = GetDlgItem(hwnd1,IDC_EDIT4);
  366.             break;
  367.         case 4:
  368.             hTemp = GetDlgItem(hwnd1,IDC_EDIT5);
  369.             break;
  370.         }      
  371.         SendMessageA(hTemp,LB_ADDSTRING,NULL,(LPARAM)buf);  // непосредственный вывод в ListBox
  372.         Sleep(200);
  373.  
  374.         Func_Sync_Clear(t);
  375.         if ( t == 3)
  376.         {
  377.             SetEvent(event2);
  378.         }
  379.     }
  380. }
  381.  
  382. // поток сортировки элементов массива в порядке возрастания
  383. void SortThreadFunc(void *v)
  384. {
  385.     int temp,k;
  386.    
  387.     while (process)
  388.     {
  389.         Func_Sync_Init(t); 
  390.         if ( t == 3)
  391.         {
  392.             WaitForSingleObject(event2,INFINITE);
  393.         }
  394.  
  395.         for (int i = 1; i < size; i++)          // сортировка массива
  396.             for (int j = 0; j < size-1; j++)    // методом пузырька
  397.                 if (matrix[i]<matrix[j])
  398.                 {
  399.                     temp = matrix[i];
  400.                     matrix[i] = matrix[j];
  401.                     matrix[j] = temp;
  402.                 }
  403.        
  404.         Func_Sync_Clear(t);
  405.         if ( t == 3)
  406.         {
  407.             SetEvent(event3);
  408.         }
  409.     }
  410. }
Add Comment
Please, Sign In to add comment