Advertisement
uzimane_

mnogopotok 5

Oct 30th, 2020
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.23 KB | None | 0 0
  1. #include <windows.h>
  2. #include <iostream>
  3. #include <random>
  4. #include <mutex>
  5. using namespace std;
  6.  
  7.  
  8.  
  9. mutex mtx;
  10. bool flag = true;
  11. condition_variable cv;
  12.  
  13.  
  14.  
  15. BOOL Ctrl_C(DWORD fdwCtrlType) {
  16.     switch (fdwCtrlType) {
  17.     case CTRL_C_EVENT: {
  18.         lock_guard <mutex> lck(mtx);
  19.         flag = false;
  20.         cv.notify_all();
  21.         return TRUE;
  22.     }
  23.     }
  24. }
  25.  
  26.  
  27.  
  28. class Request
  29. {
  30. public:
  31.     int group;
  32.     int type;
  33.  
  34.     Request(int groupInput, int typeInput)
  35.     {
  36.         group = groupInput;
  37.         type = typeInput;
  38.     }
  39. };
  40.  
  41.  
  42.  
  43. class Queue
  44. {
  45. public:
  46.     vector <Request> queue;
  47.     int beignTaskNumber;
  48.  
  49.     int PopRequest(int group) { //выбираем запрос который  будет выполняться
  50.         mtx.lock();
  51.  
  52.         Request FirstTask(-1, 0);
  53.         beignTaskNumber = -1;
  54.  
  55.         for (int i = 0; i < queue.size(); ++i) {
  56.             if (queue[i].group == group) {
  57.                 if (queue[i].type > FirstTask.type) {
  58.                     FirstTask.group = queue[i].group;
  59.                     FirstTask.type = queue[i].type;
  60.                     beignTaskNumber = i;
  61.                 }
  62.             }
  63.         }
  64.  
  65.         if (beignTaskNumber != -1) {
  66.             queue.erase(queue.begin() + beignTaskNumber);
  67.         }
  68.  
  69.         mtx.unlock();
  70.         cv.notify_all();
  71.         return FirstTask.type;
  72.     }
  73. };
  74.  
  75.  
  76.  
  77. class Generator {
  78. public:
  79.  
  80.     static Queue* reqQueue;
  81.     int size;
  82.     int groupsAmount;
  83.     bool flagGen = true;
  84.     thread thr;
  85.     mutex ul_mtx;
  86.  
  87.     Generator(int sizeInput, int groupsAmountInput) {
  88.         size = sizeInput;
  89.         groupsAmount = groupsAmountInput;
  90.         thr = thread(&Generator::GenerateTasks, this);
  91.     }
  92.  
  93.     void GenerateTasks() {
  94.         while (flag) {
  95.  
  96.             while (true) {
  97.                 Sleep(1000 + rand() % 5000);
  98.  
  99.                 if (this->size - reqQueue->queue.size()) { // если заполнили выходим
  100.                     break;
  101.                 }
  102.             }
  103.  
  104.             int newReqsAmount = rand() % (this->size - reqQueue->queue.size() + 1);
  105.  
  106.             for (int i = 0; i < newReqsAmount; ++i) {
  107.                 Request newTask(-1, 0);
  108.                 newTask.group = rand() % groupsAmount + 1;
  109.                 newTask.type = rand() % 3 + 1;
  110.                 reqQueue->queue.push_back(newTask);
  111.             }
  112.         }
  113.         flagGen = false;
  114.         return;
  115.     }
  116. };
  117.  
  118.  
  119.  
  120. class Device {
  121. public:
  122.  
  123.     static Queue* reqQueue;
  124.     thread thr;
  125.     int group;
  126.     int type = 0;
  127.     int time = 0;
  128.  
  129.  
  130.     void ProcessTask() {
  131.         while (flag || reqQueue->queue.size() != 0 || time != 0) {
  132.             if (time == 0) {
  133.                 if (type = reqQueue->PopRequest(group)) {
  134.                     time = 3 + rand() % 8;
  135.                 }
  136.             }
  137.             else {
  138.                 --time;
  139.             }
  140.  
  141.             Sleep(1000);
  142.         }
  143.     }
  144. };
  145.  
  146. Queue queue;
  147. Queue* Device::reqQueue = &queue;
  148. Queue* Generator::reqQueue = &queue;
  149.  
  150. int main() {
  151.     SetConsoleCtrlHandler((PHANDLER_ROUTINE)Ctrl_C, TRUE);
  152.     srand(time(nullptr));
  153.  
  154.     int ctr = 0;
  155.  
  156.     int queueSize, groupsAmount, groupsSize;
  157.     cout << "Storage size: ";
  158.     cin >> queueSize;
  159.     cout << "Groups amount: ";
  160.     cin >> groupsAmount;
  161.     cout << "Groups number: ";
  162.     cin >> groupsSize;
  163.     cout << endl;
  164.  
  165.     Device* devices = new Device[groupsAmount * groupsSize];
  166.     Generator generator(queueSize, groupsAmount);
  167.  
  168.  
  169.     for (int i = 0; i < groupsAmount * groupsSize; ++i) {
  170.         devices[i].group = i % groupsAmount + 1;
  171.         devices[i].thr = thread(&Device::ProcessTask, &devices[i]);
  172.     }
  173.  
  174.  
  175.     while (true) {
  176.         system("cls");
  177.  
  178.         if (generator.flagGen == true)
  179.             cout << "Generator:  ON" << endl;
  180.         else
  181.             cout << "Generator:  OFF" << endl;
  182.  
  183.         cout << "Queue consists :  " << queue.queue.size() << " of " << queueSize << " requests" << endl << endl;
  184.  
  185.         ctr = 0;
  186.  
  187.         for (int i = 0; i < groupsAmount; i++) {
  188.             cout << "Groups:  " << i + 1 << endl;
  189.            
  190.            
  191.  
  192.             for (int j = 0; j < groupsSize; j++)
  193.             {
  194.                 cout << "  " << j + 1 << ":";
  195.                 if (devices[i + groupsAmount * j].time) {
  196.                     cout << "   " << devices[i + groupsAmount * j].time << " sec. " << "type " << devices[i + groupsAmount * j].type << endl;
  197.                    
  198.                 }
  199.                 else {
  200.                     cout << "   " << "sleeping ..." << endl;
  201.                     ctr++;
  202.                 }
  203.             }
  204.             cout << endl << endl;
  205.         }
  206.  
  207.         if (generator.flagGen == false and queue.queue.size() == 0 and ctr == groupsAmount * groupsSize) {
  208.             generator.thr.join();
  209.             cout << endl;
  210.             for (int i = 0; i < groupsAmount * groupsSize; i++) {
  211.                 devices[i].thr.join();
  212.                 cout << "Group " << i / groupsSize + 1 << " device " << i % groupsSize + 1 << " thread terminated." << endl;
  213.             }
  214.             cout << endl << "Main thread terminated." << endl;
  215.             break;
  216.         }
  217.         Sleep(1000);
  218.     }
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement