Advertisement
Guest User

Untitled

a guest
Aug 18th, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.13 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <pthread.h>
  7. #include <semaphore.h>
  8.  
  9. using namespace std;
  10.  
  11. //sem_t semCout; // zorgt voor mutual excusive gebruik van cout (1 thread tegelijk).
  12.  
  13. int foodCounter=0;           // teller voor het aantal gevulde plaatsen van de buffer
  14.  
  15. pthread_mutex_t mbuffer = PTHREAD_MUTEX_INITIALIZER; //mutex object om tegelijk de buffer bewerken te voorkomen
  16. pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;  //mutex object voor conditionele variabelen
  17. pthread_mutex_t mcout = PTHREAD_MUTEX_INITIALIZER; //mutex object om tegelijk de output bewerken te voorkomen
  18. pthread_cond_t isErEten = PTHREAD_COND_INITIALIZER;//als er eten is
  19. pthread_cond_t isHijVol = PTHREAD_COND_INITIALIZER;//als hij vol is
  20.  
  21.  
  22. void check_errno(int error) {
  23.     if (error<0) {
  24.         perror("Error");
  25.         exit(EXIT_FAILURE);
  26.     }
  27. }
  28.  
  29. void check(int error) {
  30.     if (error!=0) {
  31.         cerr<<"Error: "<<strerror(error)<<endl;
  32.         exit(EXIT_FAILURE);
  33.     }
  34. }
  35.  
  36. template<typename T, int size>   // size moet een macht van 2 zijn (blijkt verderop)!
  37. class CircularBuffer {
  38. public:
  39.     CircularBuffer();            // constructor zorgt voor de initialisatiie van de datamembers
  40.     ~CircularBuffer();
  41.     void put(const T& t);        // schrijf element  in de buffer. WACHT als buffer vol is!
  42.     const T get();               // lees een element uit de buffer. WACHT als buffer leeg is!
  43.      
  44. private:
  45.     T buffer[size];              // buffer voor het opslaan van size elementen van het type T
  46.     int indexGet;                // index waar het volgende element uit de buffer gelezen wordt
  47.     int indexPut;                // index waar het volgende element in de buffer geschreven wordt
  48.    
  49.    
  50.     //sem_t semMutualExclusive;    // binaire semaphore: zorgt voor wederzijdse uitsluiting
  51.     //sem_t semEmpty;              // counting semaphore: telt aantal lege plaatsen
  52.     //sem_t semFilled;             // counting semaphore: telt aantal gevulde plaatsen
  53. };
  54.  
  55. template<typename T, int size>
  56. CircularBuffer<T, size>::CircularBuffer(): indexGet(0), indexPut(0) {
  57.     //check_errno( sem_init(&semMutualExclusive, 0, 1) ); // 1 thread tegelijk toelaten in critische gebied
  58.     //check_errno( sem_init(&semEmpty, 0, size) );        // er zijn size lege plaatsen
  59.     //check_errno( sem_init(&semFilled, 0, 0) );          // er zijn 0 gevulde plaatsen
  60. }
  61.  
  62. template<typename T, int size>
  63. CircularBuffer<T, size>::~CircularBuffer() {
  64.     //check_errno( sem_destroy(&semMutualExclusive) );
  65.     //check_errno( sem_destroy(&semEmpty) );
  66.     //check_errno( sem_destroy(&semFilled) );
  67. }
  68.  
  69.  
  70. template<typename T, int size>
  71. void CircularBuffer<T, size>::put(const T& t) {
  72.     //check_errno( sem_wait(&semEmpty) );             // verlaag het aantal lege plaatsen. WACHT als er geen lege plaatsen zijn!
  73.     pthread_mutex_lock(&m);                    
  74.     while(foodCounter>=size)
  75.         pthread_cond_wait(&isHijVol,&m);
  76.     foodCounter++;
  77.    
  78.     //check_errno( sem_wait(&semMutualExclusive) );   // ga critisch gebied binnen
  79.     check_errno(pthread_mutex_lock(&mbuffer));
  80.     buffer[indexPut++]=t;
  81.     indexPut&=size-1;                               // slim maar werkt alleen als size een macht van 2 is
  82.     //check_errno( sem_post(&semMutualExclusive) );   // verlaat critische gebied
  83.     check_errno(pthread_mutex_unlock(&mbuffer));
  84.    
  85.     pthread_cond_signal(&isErEten);
  86.     //check_errno( sem_post(&semFilled) );            //  verhoog het aantal gevulde plaatsen.
  87.     pthread_mutex_unlock(&m);
  88. }
  89.  
  90. template<typename T, int size>
  91. const T CircularBuffer<T, size>::get() {
  92.    
  93.     //check_errno( sem_wait(&semFilled) );            // verlaag het aantal gevulde plaatsen. WACHT als er geen gevulde plaatsen zijn!
  94.     pthread_mutex_lock(&m);
  95.     while(foodCounter<=0)
  96.         pthread_cond_wait(&isErEten,&m);
  97.     foodCounter--;
  98.        
  99.     //check_errno( sem_wait(&semMutualExclusive) );   // ga critische gebied binnen
  100.     check_errno(pthread_mutex_lock(&mbuffer));
  101.     T c(buffer[indexGet++]);
  102.     indexGet&=size-1;                               // slim maar werkt alleen als size een macht van 2 is
  103.     //check_errno( sem_post(&semMutualExclusive) );   // verlaat critische gebied
  104.     check_errno(pthread_mutex_unlock(&mbuffer));
  105.    
  106.     pthread_cond_signal(&isHijVol);
  107.     //check_errno( sem_post(&semEmpty) );             // verhoog het aantal lege plaatsen
  108.     pthread_mutex_unlock(&m);
  109.     return c;
  110. }
  111.  
  112. CircularBuffer<char, 4> b;
  113.  
  114. void* producer(void* arg) { // functie voor producer thread
  115.     char c(*static_cast<char*>(arg));
  116.     pthread_mutex_lock(&mcout); //check_errno( sem_wait(&semCout) );
  117.     cout<<"Thread: "<<pthread_self()<<" met arg: "<<c<< " gestart"<<endl;
  118.     pthread_mutex_unlock(&mcout);   //check_errno( sem_post(&semCout) );
  119.     for (int i(0); i<1000; ++i) {
  120.         b.put(c);
  121.     }
  122.     pthread_mutex_lock(&mcout); //check_errno( sem_wait(&semCout) );
  123.     cout<<"Thread: "<<pthread_self()<<" gestopt"<<endl;
  124.     pthread_mutex_unlock(&mcout);   //check_errno( sem_post(&semCout) );
  125. }
  126.  
  127. void* consumer(void*) { // functie voor consumer thread
  128.     pthread_mutex_lock(&mcout); //check_errno( sem_wait(&semCout) );
  129.     cout<<"Thread: "<<pthread_self()<<" gestart"<<endl;
  130.     pthread_mutex_unlock(&mcout);   //check_errno( sem_post(&semCout) );
  131.     for (int i(0); i<2000; ++i) {
  132.         char c(b.get());
  133.         pthread_mutex_lock(&mcout); //check_errno( sem_wait(&semCout) );
  134.         cout<<c;
  135.         pthread_mutex_unlock(&mcout);   //check_errno( sem_post(&semCout) );
  136.     }
  137.     pthread_mutex_lock(&mcout); //check_errno( sem_wait(&semCout) );
  138.     cout<<"Thread: "<<pthread_self()<<" gestopt"<<endl;
  139.     pthread_mutex_unlock(&mcout);   //check_errno( sem_post(&semCout) );
  140. }
  141.  
  142. int main(int argc, char *argv[]) {
  143.     // De main thread moet de hoogste prioriteit hebben omdat deze thread de andere threads start en
  144.     // we willen de onderlinge wisselwerking van deze threads bestuderen!
  145.    
  146.     sched_param sp;
  147.     int p;
  148.     check( pthread_getschedparam(pthread_self(), &p, &sp) );
  149.     sp.sched_priority=60;
  150.     check( pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp) );
  151.  
  152.     if (argc!=4) {
  153.         cerr<<"Usage: opdr1.out <Priority Consumer> <Priority Frikadel Producer> <Priority Kroket Producer>"<<endl;
  154.         exit (-1);
  155.     }
  156.  
  157.     int prioc(atoi(argv[1]));
  158.     int priop1(atoi(argv[2]));
  159.     int priop2(atoi(argv[3]));
  160.  
  161.     cout<<"Output voor Consumer priority = "<<prioc
  162.         <<" Frikadel Producer priority = "<<priop1
  163.         <<" Kroket Producer priority = "<<priop2
  164.         <<endl;
  165.  
  166.     //check_errno( sem_init(&semCout, 0, 1) );
  167.  
  168.     pthread_attr_t ptac, ptap1, ptap2;
  169.  
  170.     check( pthread_attr_init(&ptac) );
  171.     check( pthread_attr_init(&ptap1) );
  172.     check( pthread_attr_init(&ptap2) );
  173.  
  174.     check( pthread_attr_setinheritsched(&ptac, PTHREAD_EXPLICIT_SCHED) );
  175.     check( pthread_attr_setinheritsched(&ptap1, PTHREAD_EXPLICIT_SCHED) );
  176.     check( pthread_attr_setinheritsched(&ptap2, PTHREAD_EXPLICIT_SCHED) );
  177.  
  178.     check( pthread_attr_setschedpolicy(&ptac, SCHED_FIFO) );
  179.     check( pthread_attr_setschedpolicy(&ptap1, SCHED_FIFO) );
  180.     check( pthread_attr_setschedpolicy(&ptap2, SCHED_FIFO) );
  181.  
  182.     sched_param spc, spp1, spp2;
  183.  
  184.     check( pthread_attr_getschedparam(&ptac, &spc) );
  185.     check( pthread_attr_getschedparam(&ptap1, &spp1) );
  186.     check( pthread_attr_getschedparam(&ptap2, &spp2) );
  187.  
  188.     spc.sched_priority=prioc;
  189.     spp1.sched_priority=priop1;
  190.     spp2.sched_priority=priop2;
  191.  
  192.     check( pthread_attr_setschedparam(&ptac, &spc) );
  193.     check( pthread_attr_setschedparam(&ptap1, &spp1) );
  194.     check( pthread_attr_setschedparam(&ptap2, &spp2) );
  195.  
  196.     pthread_t ptp1, ptp2, ptc;
  197.  
  198.     char frikadel('F');
  199.     char kroket('K');
  200.  
  201.     check( pthread_create(&ptc, &ptac, consumer, 0) );
  202.     check( pthread_create(&ptp1, &ptap1, producer, static_cast<void*>(&frikadel)) );
  203.     check( pthread_create(&ptp2, &ptap2, producer, static_cast<void*>(&kroket)) );
  204.  
  205.     check( pthread_join(ptc, 0) );
  206.     check( pthread_join(ptp1, 0) );
  207.     check( pthread_join(ptp2, 0) );
  208.  
  209.     //check_errno( sem_destroy(&semCout) );
  210.  
  211.     return EXIT_SUCCESS;
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement