Advertisement
Mysoft

Untitled

Apr 26th, 2021
1,184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "pthread.h"
  4. #include "semaphore.h"
  5.  
  6. typedef struct GlobalState {
  7.     pthread_mutex_t   ActMutex;
  8.     int               iFanPerType[2];  
  9.     int               MustJoinCaptain;
  10.     int               FansRemaining;
  11.     pthread_t         aFanCarThread[4];
  12.     pthread_mutex_t   BeginNewCar;
  13.     pthread_barrier_t JoinTheCar;  
  14.     sem_t             DoneSemaphore;
  15. } GlobalState;
  16.  
  17. GlobalState g_tState;
  18.  
  19. void *FanThread(void *arg) {
  20.     int n, iFan = (int)arg, iFansInCar;
  21.     pthread_t tid = pthread_self();
  22.    
  23.     //show the looking for message right after thread creation
  24.     pthread_mutex_lock(&g_tState.ActMutex);
  25.   printf("Thread ID: %lli, Team: %c, I am looking for a car\n",tid,'A'+iFan);  
  26.     pthread_mutex_unlock(&g_tState.ActMutex);
  27.        
  28.     while (1) {    
  29.       pthread_mutex_lock(&g_tState.ActMutex);      
  30.       //clean up last captain thread if any
  31.         if (g_tState.MustJoinCaptain) {
  32.           pthread_join(g_tState.aFanCarThread[3], NULL );
  33.             g_tState.MustJoinCaptain = 0;
  34.       }
  35.         //number of fans on car is #A + #B
  36.         iFansInCar = g_tState.iFanPerType[0]+g_tState.iFanPerType[1];      
  37.         //allowed combinatios are 2:2 or 4:0
  38.         if ((iFansInCar < 3) || (g_tState.iFanPerType[iFan] & 1)) {        
  39.       //set the TID for this fan on a car slot (so we can wait & cleanup)
  40.             g_tState.aFanCarThread[iFansInCar] = tid;
  41.             g_tState.iFanPerType[iFan]++;
  42.            
  43.             //printf("Thread ID: %lli, Team: %c, I am looking for a car\n",tid,'A'+iFan);  
  44.            
  45.             // wait for 4 compatible fans to arrive before entering the car
  46.             pthread_mutex_unlock(&g_tState.ActMutex);          
  47.             pthread_barrier_wait( &g_tState.JoinTheCar );                      
  48.             pthread_mutex_trylock(&g_tState.BeginNewCar);
  49.             pthread_mutex_lock(&g_tState.ActMutex);
  50.            
  51.             printf("Thread ID: %lli, Team: %c, I have found a spot in a car\n",tid,'A'+iFan);  
  52.             pthread_mutex_unlock(&g_tState.ActMutex);
  53.             //if this fan will fill a car, then it becomes the captain and a car is finished
  54.             if (iFansInCar==3) {               
  55.                 //so then we can "join" the previous 3 fan threads that finished (thread cleanup)              
  56.                 for (n=0 ; n<iFansInCar ; n++) {
  57.                     pthread_join(g_tState.aFanCarThread[n], NULL );
  58.                 }              
  59.                 pthread_mutex_lock(&g_tState.ActMutex);        
  60.                 printf("Thread ID: %lli, Team: %c, I am the captain and driving the car\n",tid,'A'+iFan);
  61.                 g_tState.iFanPerType[0] = g_tState.iFanPerType[1] = 0;
  62.                 g_tState.MustJoinCaptain = 1;
  63.                 g_tState.FansRemaining -= 4;
  64.                 if (!g_tState.FansRemaining) { sem_post( &g_tState.DoneSemaphore ); }
  65.                 pthread_mutex_unlock(&g_tState.ActMutex);
  66.                 pthread_mutex_unlock(&g_tState.BeginNewCar);
  67.                 //when finishing a car a new one can start...              
  68.             }
  69.             //fan is inside a car so exit the thread           
  70.             break;
  71.         } else {           
  72.             //printf("Thread ID: %lli, Team: %c, waiting for a new car...\n",tid,'A'+iFan);
  73.             pthread_mutex_unlock(&g_tState.ActMutex);
  74.             //wait for a new car
  75.             pthread_mutex_lock(&g_tState.BeginNewCar);
  76.             pthread_mutex_unlock(&g_tState.BeginNewCar);           
  77.         }
  78.     }
  79.        
  80. }
  81.  
  82. void ManageThreads(int iNumA,int iNumB) {
  83.    
  84.     int i;
  85.     pthread_t tid;
  86.    
  87.   //number of fans on each group must be even
  88.     if ((iNumA & 1) || (iNumB & 1)) return;
  89.     //total number must be a multiple of 4
  90.     if ((iNumA+iNumB) & 3) return; 
  91.    
  92.     //initialize global state
  93.     g_tState.FansRemaining = iNumA+iNumB;
  94.     g_tState.MustJoinCaptain = 0;
  95.     pthread_mutex_init(&g_tState.ActMutex, NULL);  
  96.     pthread_mutex_init(&g_tState.BeginNewCar, NULL);   
  97.     //pthread_mutex_lock(&g_tState.BeginNewCar);
  98.     pthread_barrier_init(&g_tState.JoinTheCar, NULL, 4);   
  99.     sem_init(&g_tState.DoneSemaphore, 0, 0);
  100.    
  101.     // creating threads
  102.     for ( i=0 ; i<iNumA ; i++ ) {
  103.     pthread_create(&tid, NULL, &FanThread, (void*)0);  
  104.     }  
  105.    
  106.     for ( i=0 ; i<iNumB ; i++ ) {
  107.     pthread_create(&tid, NULL, &FanThread, (void*)1);  
  108.     }
  109.    
  110.     //waiting for all fans to depart
  111.     sem_wait( &g_tState.DoneSemaphore );   
  112.     //waiting for last thread to finish
  113.     pthread_join(g_tState.aFanCarThread[3], NULL );
  114.    
  115.     //free resources
  116.     pthread_barrier_destroy(&g_tState.JoinTheCar); 
  117.     sem_destroy(&g_tState.DoneSemaphore);
  118.     pthread_mutex_destroy(&g_tState.ActMutex);
  119.     pthread_mutex_destroy(&g_tState.BeginNewCar);
  120. }
  121.  
  122. int main(int argc, char *argv[]) {
  123.     int iNumA,iNumB;
  124.        
  125.     //number of arguments must be 3...
  126.     //ProgramName , FansA , FansB
  127.     if (argc == 3) {   
  128.         //fans of different members
  129.         iNumA = atoi(argv[1]);
  130.         iNumB = atoi(argv[2]); 
  131.       ManageThreads( iNumA , iNumB );
  132.     }
  133.            
  134.     puts("main terminates");   
  135.     return 0;
  136. }
  137.    
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement