Facebook
From Harmless Meerkat, 3 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 60
  1. #include "stdafx.h"
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <windows.h>
  5. #include <ctime>
  6. #include <conio.h>
  7.  
  8. using namespace std;
  9.  
  10. struct TMySemaphore {           //Наш семафор
  11.         HANDLE HEvent;//Событие
  12.         int Count;//Сколько ещё можно внести потоков
  13.         int Max;//Макс. кол-во
  14.         int waiting;//Сколько ждет
  15. }       Sem;
  16. HANDLE h[5];    //Дескрипторы потоков
  17. int d[5];//Идентификаторы потоков
  18. int q[10];//Общий ресурс(массив)
  19. int i;
  20. DWORD dwError;
  21. LPTSTR hlocal;
  22.  
  23. void CreateMySemaphore(TMySemaphore S, int init,int max, string name) {
  24.         S.Count = init;//Сколько еще может войти потоков(создаётся счётчик)
  25.         S.Max = max;//Макс. число потоков, которое может войти
  26.         if (init > max) {
  27.                 cout << "Start value must be less then maximal\n" << GetLastError();
  28.                 _getch();
  29.         }
  30.         S.HEvent = CreateEvent(NULL, false, true, (LPCWSTR)&name);//Создаём событие
  31.         S.waiting = 0;  //Сколько ждет
  32. }
  33.  
  34. void WaitForMySemaphore(TMySemaphore S) {//Ждём семафора
  35.         if (S.Count > 0) {//Если еще может кто-то войти
  36.                 S.Count--;//Уменьшаем
  37.         }
  38.         else {
  39.                 S.waiting++;//Увел. число ждущих
  40.                 WaitForSingleObject(S.HEvent, INFINITE);//Ждём, когда кто-нибудь просигналит событие(освободит семафор)
  41.         }
  42. }
  43.  
  44. void ReleaseMySemaphore(TMySemaphore S) {//Освоб. семафор
  45.         if (S.Count == 0) {//Если заполнено
  46.                 SetEvent(S.HEvent);//Сигналим событие
  47.         }
  48.         if (S.waiting > 0) {//Если кто-то ждет
  49.                 S.waiting--;//Уменьшаем число ждущих
  50.         }
  51.         else {
  52.                 S.Count++;//Увел. число возможных потоков
  53.         }
  54.         if (S.Count > S.Max) {
  55.                 cout << "Too many!!!\n";
  56.         }
  57. }
  58.  
  59. void CloseMySemaphore(TMySemaphore S) {//Закрываем семафор
  60.         CloseHandle(S.HEvent);//Закрываем дескриптор события
  61. }
  62.  
  63. DWORD proc1(DWORD dd) {//Процедура добавляющих потоков
  64.         int x, i, j, ip;
  65.         DWORD id;
  66.  
  67.         id = GetCurrentThreadId();//получаем идентификатор потока
  68.         ip = 0;//Пока еще не нашли
  69.         for (i = 1; i <= 5; i++) {//Ищем номер потока
  70.                 if (d[i] == id) ip = i;
  71.         }
  72.         for (i = 1; i <= 5; i++) {//Меняем пять чисел
  73.                         //Пишем состояние семафора
  74.                 cout << ip << " Can enter:" << Sem.Count << " Are waiting:" << Sem.waiting << "\n";
  75.                 cout << ip << " is waiting\n";
  76.                 WaitForMySemaphore(Sem);//Ждем семафора
  77.                 Sleep(1000);//задержка(1 сек.)
  78.                 cout << ip << " Can enter:" << Sem.Count << " Are waiting:" << Sem.waiting << "\n";
  79.                 j = (rand() % 10) + 1;//[1..10]
  80.                 x = rand() % 100;
  81.                 //Пишем, какое число мы заменили    
  82.                 cout << ip << " Thread#" << ip << " has put a number into place:" << j << "-" << x << "\n";
  83.                 q[j] = x;//Меняем в массиве сл. число на сл. месте
  84.                 cout << ip << " Can enter:" << Sem.Count << " Are waiting:" << Sem.waiting << "\n";
  85.                 Sleep(1000);
  86.                 ReleaseMySemaphore(Sem);//Освоб семафор
  87.                 cout << ip << " Releasing\n";
  88.                 cout << ip << " Can enter:" << Sem.Count << " Are waiting:" << Sem.waiting << "\n";
  89.         }
  90.         return 0;
  91. }
  92.  
  93. DWORD proc2(DWORD dd) {//процедура вынимающего потока
  94.         int i, j, x, ip;
  95.         DWORD id;
  96.  
  97.         id = GetCurrentThreadId();//получаем идентификатор потока
  98.         ip = 0;
  99.         for (i = 1; i <= 5; i++) {//Ищем номер потока
  100.                 if (d[i] == id) ip = i;
  101.         }
  102.         for (i = 1; i <= 15; i++) {//смотрим случайный элемент массива
  103.                         //Состояние семафора
  104.                 cout << ip << " Can enter:" << Sem.Count << " Are waiting:" << Sem.waiting << "\n";
  105.                 cout << ip << " Waiting\n";
  106.                 WaitForMySemaphore(Sem);//Ждём семафора
  107.                 Sleep(1000);
  108.                 cout << ip << " Can enter:" << Sem.Count << " Are waiting:" << Sem.waiting << "\n";
  109.                 j = (rand() % 10) + 1; //Место
  110.                 x = q[j];//Вынимаем число из массива
  111.                           //Какое число мы посмотрели
  112.                 cout << ip << " Thread#" << ip << " has got a number from place:" << j << "-" << x << "\n";
  113.                 cout << ip << " Can enter:" << Sem.Count << " Are waiting:" << Sem.waiting << "\n";
  114.                 Sleep(1000);
  115.                 ReleaseMySemaphore(Sem);//Освоб. семафор
  116.                 cout << ip << " Releasing\n";
  117.                 cout << ip << " Can enter:" << Sem.Count << " Are waiting:" << Sem.waiting << "\n";
  118.         }
  119.         return 0;
  120. }
  121.  
  122.  
  123. void main() {//Основная программа
  124.         setlocale(LC_ALL, "russian_russia");
  125.         srand(time(NULL));
  126.  
  127.         //AllocConsole;//Создаем консоль
  128.         cout << "Was:";
  129.         for (i = 1; i <= 10; i++) {//Заполняем и выводим массив
  130.                 q[i] = rand() % 100;
  131.                 cout << q[i] << " ";
  132.         }
  133.         cout << "\n";
  134.         CreateMySemaphore(Sem, 3, 3, "EventSemaphore");//Созд. семафор
  135.         for (i = 1; i <= 3; i++) {
  136.                 h[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)proc1, NULL, 0, (LPDWORD)d[i]);//Создаём 3 кладущих потока
  137.                 if (h[i] == 0)  cout << (GetLastError());
  138.         }
  139.         for (i = 4; i <= 5; i++) {
  140.                 h[i]  = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)proc2, NULL, 0, (LPDWORD)d[i]);//Создаём 2 вынимающих потока
  141.                 dwError = GetLastError();
  142.                 if (h[i] == 0) cout << (dwError);
  143.                         // FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ALLOCATE_BUFFER, nil, dwError; MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); hlocal; 0; nil )
  144.         }
  145.         WaitForMultipleObjects(5, h,true, INFINITE);//Ждём завершения всех потоков
  146.         for (i = 1; i <= 5; i++) {
  147.                 CloseHandle(h[i]);//Закрываем дескрипторы потоков
  148.         }
  149.         CloseMySemaphore(Sem);//Закрываем семафор
  150.         cout << "Is:"; //то, что получилось
  151.         for (i = 1; i <= 10; i++) { //Выводим массив
  152.                 cout << q[i] << " ";
  153.         }
  154.         _getch();
  155.         //FreeConsole;//Закрываем консоль
  156. }