Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <iostream>
- #include <random>
- #include <mutex>
- using namespace std;
- mutex mtx;
- bool flag = true;
- condition_variable cv;
- BOOL Ctrl_C(DWORD fdwCtrlType) {
- switch (fdwCtrlType) {
- case CTRL_C_EVENT: {
- lock_guard <mutex> lck(mtx);
- flag = false;
- cv.notify_all();
- return TRUE;
- }
- }
- }
- class Request
- {
- public:
- int group;
- int type;
- Request(int groupInput, int typeInput)
- {
- group = groupInput;
- type = typeInput;
- }
- };
- class Queue
- {
- public:
- vector <Request> queue;
- int beignTaskNumber;
- int PopRequest(int group) { //выбираем запрос который будет выполняться
- mtx.lock();
- Request FirstTask(-1, 0);
- beignTaskNumber = -1;
- for (int i = 0; i < queue.size(); ++i) {
- if (queue[i].group == group) {
- if (queue[i].type > FirstTask.type) {
- FirstTask.group = queue[i].group;
- FirstTask.type = queue[i].type;
- beignTaskNumber = i;
- }
- }
- }
- if (beignTaskNumber != -1) {
- queue.erase(queue.begin() + beignTaskNumber);
- }
- mtx.unlock();
- cv.notify_all();
- return FirstTask.type;
- }
- };
- class Generator {
- public:
- static Queue* reqQueue;
- int size;
- int groupsAmount;
- bool flagGen = true;
- thread thr;
- mutex ul_mtx;
- Generator(int sizeInput, int groupsAmountInput) {
- size = sizeInput;
- groupsAmount = groupsAmountInput;
- thr = thread(&Generator::GenerateTasks, this);
- }
- void GenerateTasks() {
- while (flag) {
- while (true) {
- Sleep(1000 + rand() % 5000);
- if (this->size - reqQueue->queue.size()) { // если заполнили выходим
- break;
- }
- }
- int newReqsAmount = rand() % (this->size - reqQueue->queue.size() + 1);
- for (int i = 0; i < newReqsAmount; ++i) {
- Request newTask(-1, 0);
- newTask.group = rand() % groupsAmount + 1;
- newTask.type = rand() % 3 + 1;
- reqQueue->queue.push_back(newTask);
- }
- }
- flagGen = false;
- return;
- }
- };
- class Device {
- public:
- static Queue* reqQueue;
- thread thr;
- int group;
- int type = 0;
- int time = 0;
- void ProcessTask() {
- while (flag || reqQueue->queue.size() != 0 || time != 0) {
- if (time == 0) {
- if (type = reqQueue->PopRequest(group)) {
- time = 3 + rand() % 8;
- }
- }
- else {
- --time;
- }
- Sleep(1000);
- }
- }
- };
- Queue queue;
- Queue* Device::reqQueue = &queue;
- Queue* Generator::reqQueue = &queue;
- int main() {
- SetConsoleCtrlHandler((PHANDLER_ROUTINE)Ctrl_C, TRUE);
- srand(time(nullptr));
- int ctr = 0;
- int queueSize, groupsAmount, groupsSize;
- cout << "Storage size: ";
- cin >> queueSize;
- cout << "Groups amount: ";
- cin >> groupsAmount;
- cout << "Groups number: ";
- cin >> groupsSize;
- cout << endl;
- Device* devices = new Device[groupsAmount * groupsSize];
- Generator generator(queueSize, groupsAmount);
- for (int i = 0; i < groupsAmount * groupsSize; ++i) {
- devices[i].group = i % groupsAmount + 1;
- devices[i].thr = thread(&Device::ProcessTask, &devices[i]);
- }
- while (true) {
- system("cls");
- if (generator.flagGen == true)
- cout << "Generator: ON" << endl;
- else
- cout << "Generator: OFF" << endl;
- cout << "Queue consists : " << queue.queue.size() << " of " << queueSize << " requests" << endl << endl;
- ctr = 0;
- for (int i = 0; i < groupsAmount; i++) {
- cout << "Groups: " << i + 1 << endl;
- for (int j = 0; j < groupsSize; j++)
- {
- cout << " " << j + 1 << ":";
- if (devices[i + groupsAmount * j].time) {
- cout << " " << devices[i + groupsAmount * j].time << " sec. " << "type " << devices[i + groupsAmount * j].type << endl;
- }
- else {
- cout << " " << "sleeping ..." << endl;
- ctr++;
- }
- }
- cout << endl << endl;
- }
- if (generator.flagGen == false and queue.queue.size() == 0 and ctr == groupsAmount * groupsSize) {
- generator.thr.join();
- cout << endl;
- for (int i = 0; i < groupsAmount * groupsSize; i++) {
- devices[i].thr.join();
- cout << "Group " << i / groupsSize + 1 << " device " << i % groupsSize + 1 << " thread terminated." << endl;
- }
- cout << endl << "Main thread terminated." << endl;
- break;
- }
- Sleep(1000);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement