Guest User

Untitled

a guest
Nov 4th, 2015
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.90 KB | None | 0 0
  1. #include "stdafx.h"
  2.            
  3.  
  4. #include <Windows.h>
  5. #include <process.h>
  6. #include <ctime>
  7. #include <conio.h>
  8. #include <iostream>
  9. #include <iomanip>
  10. #include <fstream>
  11. #include <sstream>
  12. #include <queue>
  13.  
  14. int MAXSLOTS = 50;                      // max available slots
  15. int NUM_CONSUMERS = 10;
  16. int NUM_PRODUCERS = 10;
  17. CRITICAL_SECTION logCritSection;        // critical section for log purpose
  18. HANDLE mutex, empty, full;
  19.  
  20. // container shared between consumers
  21. std::queue<int> queue;
  22. bool running = true;
  23.  
  24. // thread functions
  25. void produce(void*);
  26. void consume(void*);
  27.  
  28. // logging function
  29. void log(const std::string& message);
  30. // get current date & time
  31. std::string getTimestamp();
  32.  
  33. // generate new item
  34. int genRand();
  35. // fibonacci recursive generator
  36. int fibo(int x);
  37.  
  38. int main(int argc, char** argv)
  39. {
  40.     // redefining MAXSLOTS variable with input from prompt
  41.     if (argc > 3)
  42.     {
  43.         MAXSLOTS      = atoi(argv[1]);
  44.         NUM_PRODUCERS = atoi(argv[2]);
  45.         NUM_CONSUMERS = atoi(argv[3]);
  46.     }
  47.  
  48.     // initialize semaphores
  49.     mutex = CreateSemaphore(NULL, 1, 1, NULL);
  50.     empty = CreateSemaphore(NULL, MAXSLOTS, MAXSLOTS, NULL);
  51.     full = CreateSemaphore(NULL, 0, 1, NULL);
  52.  
  53.     std::srand(time(0));
  54.     remove("log.txt");
  55.     InitializeCriticalSection(&logCritSection);
  56.  
  57.     std::cout << "App started" << std::endl;
  58.     log("App started");
  59.     log("Operation\tAgent\t\tSize");
  60.  
  61.     // create producer threads
  62.     for (int id = 0; id < NUM_PRODUCERS; ++id)
  63.         if (_beginthread(produce, 1024, reinterpret_cast<void*>(id)) == -1)
  64.         {
  65.             std::cout << "Error: can't launch producer thread." << std::endl;
  66.             running = false;
  67.         }
  68.  
  69.     // create consumer threads
  70.     for (int id = 0; id < NUM_CONSUMERS; ++id)
  71.     {
  72.         if (_beginthread(consume, 1024, reinterpret_cast<void*>(id)) == -1)
  73.         {
  74.             std::cout << "Error: can't launch consumer threads." << std::endl;
  75.             running = false;
  76.         }
  77.     }
  78.  
  79.     _getch();
  80.     running = false;
  81.  
  82.     std::cout << "App terminated successfully. Check log file" << std::endl;
  83.     system("pause");
  84.     log("App finished");
  85.  
  86.     DeleteCriticalSection(&logCritSection);
  87.  
  88.     return 0;
  89. }
  90.  
  91. void produce(void* producerID)
  92. {
  93.     int ID = (int)producerID;
  94.     log("Init\t\tProducer " + std::to_string(ID));
  95.     int item, size;
  96.     while (running)
  97.     {
  98.         item = genRand();
  99.         WaitForSingleObject(empty, INFINITE);
  100.         WaitForSingleObject(mutex, INFINITE);
  101.         queue.push(item);
  102.         size = queue.size();
  103.         ReleaseSemaphore(mutex, 1, NULL);
  104.         ReleaseSemaphore(full, 1, NULL);
  105.  
  106.         // logging produce
  107.         std::stringstream msg;
  108.         msg << "Write\t" << "Producer " << ID << "\t" << size;
  109.         log(msg.str());
  110.     }
  111.  
  112.     log("Exit\t\tProducer " + std::to_string(ID));
  113.     _endthread();
  114. }
  115.  
  116. void consume(void* consumerID)
  117. {
  118.     int ID = (int)consumerID;
  119.     log("Init\t\tConsumer " + std::to_string(ID));
  120.     int item, size;
  121.     while (running)
  122.     {
  123.         WaitForSingleObject(full, INFINITE);
  124.         WaitForSingleObject(mutex, INFINITE);
  125.         item = queue.back();                    // accessing item from queue
  126.         queue.pop();                        // and removing it
  127.         size = queue.size();
  128.         fibo(item);                     // calculate fibonacci to slow down
  129.         ReleaseSemaphore(mutex, 1, NULL);
  130.         ReleaseSemaphore(empty, 1, NULL);
  131.  
  132.         // logging consume
  133.         std::stringstream msg;
  134.         msg << "Read \t" << "Consumer " << ID << "\t" << size;
  135.         log(msg.str());
  136.     }
  137.  
  138.     log("Exit\t\tConsumer " + std::to_string(ID));
  139.     _endthread();
  140. }
  141.  
  142. int genRand()
  143. {
  144.     return rand() % 40;
  145. }
  146.  
  147. std::string getTimestamp() {
  148.     std::time_t t = std::time(NULL);
  149.     std::tm tm;
  150.     localtime_s(&tm, &t);
  151.     std::stringstream res;
  152.     res << std::put_time(&tm, "[%H:%M:%S]");
  153.     return res.str();
  154. }
  155.  
  156. void log(const std::string& msg)
  157. {
  158.     EnterCriticalSection(&logCritSection);
  159.     std::fstream file("log.txt", std::ios::app);
  160.     if (file.good())
  161.     {
  162.         file << getTimestamp() << " " << msg << std::endl;
  163.         file.close();
  164.     }
  165.     LeaveCriticalSection(&logCritSection);
  166. }
  167.  
  168. int fibo(int x)
  169. {
  170.     if (x == 0)
  171.     {
  172.         return 0;
  173.     }
  174.  
  175.     if (x == 1)
  176.     {
  177.         return 1;
  178.     }
  179.  
  180.     return fibo(x - 1) + fibo(x - 2);
  181. }
Advertisement
Add Comment
Please, Sign In to add comment