Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <Windows.h>
- #include <process.h>
- #include <ctime>
- #include <conio.h>
- #include <iostream>
- #include <iomanip>
- #include <fstream>
- #include <sstream>
- #include <queue>
- int MAXSLOTS = 50; // max available slots
- int NUM_CONSUMERS = 10;
- int NUM_PRODUCERS = 10;
- CRITICAL_SECTION logCritSection; // critical section for log purpose
- HANDLE mutex, empty, full;
- // container shared between consumers
- std::queue<int> queue;
- bool running = true;
- // thread functions
- void produce(void*);
- void consume(void*);
- // logging function
- void log(const std::string& message);
- // get current date & time
- std::string getTimestamp();
- // generate new item
- int genRand();
- // fibonacci recursive generator
- int fibo(int x);
- int main(int argc, char** argv)
- {
- // redefining MAXSLOTS variable with input from prompt
- if (argc > 3)
- {
- MAXSLOTS = atoi(argv[1]);
- NUM_PRODUCERS = atoi(argv[2]);
- NUM_CONSUMERS = atoi(argv[3]);
- }
- // initialize semaphores
- mutex = CreateSemaphore(NULL, 1, 1, NULL);
- empty = CreateSemaphore(NULL, MAXSLOTS, MAXSLOTS, NULL);
- full = CreateSemaphore(NULL, 0, 1, NULL);
- std::srand(time(0));
- remove("log.txt");
- InitializeCriticalSection(&logCritSection);
- std::cout << "App started" << std::endl;
- log("App started");
- log("Operation\tAgent\t\tSize");
- // create producer threads
- for (int id = 0; id < NUM_PRODUCERS; ++id)
- if (_beginthread(produce, 1024, reinterpret_cast<void*>(id)) == -1)
- {
- std::cout << "Error: can't launch producer thread." << std::endl;
- running = false;
- }
- // create consumer threads
- for (int id = 0; id < NUM_CONSUMERS; ++id)
- {
- if (_beginthread(consume, 1024, reinterpret_cast<void*>(id)) == -1)
- {
- std::cout << "Error: can't launch consumer threads." << std::endl;
- running = false;
- }
- }
- _getch();
- running = false;
- std::cout << "App terminated successfully. Check log file" << std::endl;
- system("pause");
- log("App finished");
- DeleteCriticalSection(&logCritSection);
- return 0;
- }
- void produce(void* producerID)
- {
- int ID = (int)producerID;
- log("Init\t\tProducer " + std::to_string(ID));
- int item, size;
- while (running)
- {
- item = genRand();
- WaitForSingleObject(empty, INFINITE);
- WaitForSingleObject(mutex, INFINITE);
- queue.push(item);
- size = queue.size();
- ReleaseSemaphore(mutex, 1, NULL);
- ReleaseSemaphore(full, 1, NULL);
- // logging produce
- std::stringstream msg;
- msg << "Write\t" << "Producer " << ID << "\t" << size;
- log(msg.str());
- }
- log("Exit\t\tProducer " + std::to_string(ID));
- _endthread();
- }
- void consume(void* consumerID)
- {
- int ID = (int)consumerID;
- log("Init\t\tConsumer " + std::to_string(ID));
- int item, size;
- while (running)
- {
- WaitForSingleObject(full, INFINITE);
- WaitForSingleObject(mutex, INFINITE);
- item = queue.back(); // accessing item from queue
- queue.pop(); // and removing it
- size = queue.size();
- fibo(item); // calculate fibonacci to slow down
- ReleaseSemaphore(mutex, 1, NULL);
- ReleaseSemaphore(empty, 1, NULL);
- // logging consume
- std::stringstream msg;
- msg << "Read \t" << "Consumer " << ID << "\t" << size;
- log(msg.str());
- }
- log("Exit\t\tConsumer " + std::to_string(ID));
- _endthread();
- }
- int genRand()
- {
- return rand() % 40;
- }
- std::string getTimestamp() {
- std::time_t t = std::time(NULL);
- std::tm tm;
- localtime_s(&tm, &t);
- std::stringstream res;
- res << std::put_time(&tm, "[%H:%M:%S]");
- return res.str();
- }
- void log(const std::string& msg)
- {
- EnterCriticalSection(&logCritSection);
- std::fstream file("log.txt", std::ios::app);
- if (file.good())
- {
- file << getTimestamp() << " " << msg << std::endl;
- file.close();
- }
- LeaveCriticalSection(&logCritSection);
- }
- int fibo(int x)
- {
- if (x == 0)
- {
- return 0;
- }
- if (x == 1)
- {
- return 1;
- }
- return fibo(x - 1) + fibo(x - 2);
- }
Advertisement
Add Comment
Please, Sign In to add comment