Advertisement
Guest User

Untitled

a guest
Dec 9th, 2016
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.62 KB | None | 0 0
  1. #include <iostream>
  2. #include <semaphore.h>
  3. #include <pthread.h>
  4.  
  5. sem_t canConsume;
  6. sem_t canProduce;
  7. sem_t mutex;
  8.  
  9. bool consumeFinish   = false;
  10. bool produceFinish   = false;
  11.  
  12. size_t bufferSize    = 0;
  13. unsigned int *buffer = nullptr;
  14.  
  15.  
  16. void printBuffer() {
  17.     std::cout << "Buffer: ";
  18.     for (size_t i = 0; i < bufferSize; i++) {
  19.         std::cout << buffer[i] << " ";
  20.     }
  21.     std::cout << std::endl;
  22. }
  23.  
  24.  
  25. unsigned int get_buffer() {
  26.     for (size_t i = 0; i < bufferSize; i++) {
  27.         if (buffer[i] == 1) {
  28.             buffer[i] = 0;
  29.             return (unsigned int) i;
  30.         }
  31.     }
  32. }
  33.  
  34. unsigned int push_buffer() {
  35.     for (size_t i = 0; i < bufferSize; i++) {
  36.         if (buffer[i] == 0) {
  37.             buffer[i] = 1;
  38.             return (unsigned int) i;
  39.         }
  40.     }
  41. }
  42.  
  43. void *produce(void *threadId) {
  44.     unsigned int id = *((unsigned int *) threadId);
  45.     unsigned int pos = 0;
  46.  
  47.     do {
  48.         sem_wait(&canProduce);
  49.         sem_wait(&mutex);
  50.        
  51.         // produce action
  52.         pos = push_buffer();
  53.        
  54.         sem_post(&mutex);
  55.         sem_post(&canConsume);
  56.     } while (!produceFinish);
  57.  
  58.     pthread_exit(0);
  59. }
  60.  
  61. void *consume(void *threadId) {
  62.     unsigned int id  = *((unsigned int *) threadId);
  63.     unsigned int pos = 0;
  64.    
  65.     do {
  66.         sem_wait(&canConsume);
  67.         sem_wait(&mutex);
  68.        
  69.         // consume action
  70.         pos = get_buffer();
  71.        
  72.         sem_post(&mutex);
  73.         sem_post(&canProduce);
  74.     } while (!consumeFinish);
  75.    
  76.     pthread_exit(0);
  77. }
  78.  
  79. bool validateArgs(int argc, char *argv[], int &numThreadsProducers, int &numThreadsConsumers) {
  80.     // receive arguments - validate and save
  81.     if (argc != 6) {
  82.         std::cerr << "Number of arguments invalid!" << std::endl;
  83.         return false;
  84.     }
  85.    
  86.     if (atoi(argv[1])) {
  87.         bufferSize = std::stoi(argv[1]);
  88.     } else {
  89.         std::cerr << argv[1] << ": is not valid number!" << std::endl;
  90.         return false;
  91.     }
  92.    
  93.     if (atoi(argv[2])) {
  94.         numThreadsProducers = std::stoi(argv[2]);
  95.     } else {
  96.         std::cerr << argv[2] << ": is not valid number!" << std::endl;
  97.         return false;
  98.     }
  99.    
  100.     if (strcmp(argv[3], "1") == 0 || strcmp(argv[3], "true") == 0) {
  101.         produceFinish = true;
  102.     } else if (strcmp(argv[3], "0") == 0 || strcmp(argv[3], "false") != 0) {
  103.         std::cerr << argv[3] << ": is not valid boolean!" << std::endl;
  104.         return false;
  105.     }
  106.    
  107.     if (atoi(argv[4])) {
  108.         numThreadsConsumers = std::stoi(argv[4]);
  109.     } else {
  110.         std::cerr << argv[4] << ": is not valid number!" << std::endl;
  111.         return false;
  112.     }
  113.    
  114.     if (strcmp(argv[5], "1") == 0 || strcmp(argv[5], "true") == 0) {
  115.         consumeFinish = true;
  116.     } else if (strcmp(argv[5], "0") == 0 || strcmp(argv[5], "false") != 0) {
  117.         std::cerr << argv[5] << ": is not valid boolean!" << std::endl;
  118.         return false;
  119.     }
  120.    
  121.     return true;
  122. }
  123.  
  124. int main(int argc, char *argv[]) {
  125.     int numThreadsProducers = 0, numThreadsConsumers = 0;
  126.  
  127.     // validate and save
  128.     if (!validateArgs(argc, argv, numThreadsProducers, numThreadsConsumers)) {
  129.         return -1;
  130.     }
  131.  
  132.     // initialize buffer
  133.     buffer = new unsigned int[bufferSize];
  134.     for (int i = 0; i < bufferSize; i++) {
  135.         buffer[i] = 0;
  136.     }
  137.    
  138.     // initialize semaphores
  139.     sem_init(&canProduce, 0, bufferSize);
  140.     sem_init(&canConsume, 0, 0);
  141.     sem_init(&mutex, 0, 1);
  142.    
  143.     // create threads arrays
  144.     pthread_t *consumersThreadsArray = new pthread_t[numThreadsConsumers];
  145.     pthread_t *producersThreadsArray = new pthread_t[numThreadsProducers];
  146.    
  147.     // create producers threads
  148.     for (int threadId = 0; threadId < numThreadsProducers; threadId++) {
  149.         pthread_create(&(producersThreadsArray[threadId]), NULL, produce, &threadId);
  150.     }
  151.    
  152.     // create consumers threads
  153.     for (int threadId = 0; threadId < numThreadsConsumers; threadId++) {
  154.         pthread_create(&(consumersThreadsArray[threadId]), NULL, consume, &threadId);
  155.     }
  156.    
  157.     // threads join
  158.     for (int i = 0; i < numThreadsProducers; i++) {
  159.         pthread_join(producersThreadsArray[i], nullptr);
  160.     }
  161.    
  162.     for (int i = 0; i < numThreadsConsumers; i++) {
  163.         pthread_join(consumersThreadsArray[i], nullptr);
  164.     }
  165.    
  166.     // print buffer
  167.     printBuffer();
  168.    
  169.     // delete memory
  170.     sem_destroy(&canProduce);
  171.     sem_destroy(&canConsume);
  172.     sem_destroy(&mutex);
  173.    
  174.     delete [] buffer;
  175.     delete [] consumersThreadsArray;
  176.     delete [] producersThreadsArray;
  177.    
  178.     return 0;
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement