Thread: pthread_exit()

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    5

    pthread_exit()

    The code i have below is supposed to simulate different scheduling algorithms. I am having a problem that when one of the threads finishes and exits none of the other threads will continue to run even though they are not completed. The program will merely sit and spin in the main loop. I don't know why this is occurring as i am pretty new to pthreads. Thanks.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <time.h>
    #include "myQueue.h"
    
    #define numProcessors 5
    #define false 0
    #define true 1
    int numProcesses;
    struct queueType *queue;
    pthread_mutex_t queueSem;
    int masterTime;
    pthread_cond_t timeUpdate[numProcessors];
    
    pthread_mutex_t timeSem;
    pthread_mutex_t randoSem;
    
    pthread_mutex_t outputSem;
    
    pthread_mutex_t amIDone[numProcessors];
    
    #define quantum 2
    
    void *fcfs();
    void *roundRobin();
    void *srtf();
    void *sjf();
    void *priQueue();
    
    int main(int argc, char *argv[])
    {
      int i = 0;
      int j = 0;
      int allDone = false;
      masterTime = 0;
      numProcesses = 0;
    
      char *priorityChar, *burstChar;
      int priority, burst;
      FILE *pfile;
      pthread_t fcfsThread, rrThread, srtfThread, sjfThread, priQueueThread, threads[5];
    
     
      printf("hellooo");
      queue = newQueue();
    
      pthread_mutex_init(&queueSem, NULL);
      pthread_mutex_init(&outputSem, NULL);
      pthread_mutex_init(&timeSem, NULL);
      pthread_mutex_init(&randoSem, NULL);
      
      if(argv[1] != NULL)
      {
    	  printf("%s\n", argv[1]);
    	  if(strcmp(argv[1], "-procs10.dat") == 0){
    	    argv[1] = "procs10.dat";
    	  }
    	  if(strcmp(argv[1], "-procs100.dat") == 0){
    	    argv[1] = "procs100.dat";
    	  }
    	  if(strcmp(argv[1], "-procs1000.dat") == 0){
    	    argv[1] = "procs1000.dat";
    	  }
    	  printf("%s\n", argv[1]);
      }
      pfile = fopen(argv[1], "r");
      if(pfile == NULL){
        fprintf(stderr, "ERROR: cannot open the file, please hit enter\n");
        getchar();
        exit(1);
      }
    
      while(!feof(pfile)){
        fscanf(pfile, "%s", priorityChar);
        fscanf(pfile, "\t");
        fscanf(pfile, "%s", burstChar);
        fscanf(pfile, "\n");
        priority = atoi(priorityChar);
        burst = atoi(burstChar);
        printf("priority = %d   burst = %d\n", priority, burst);
        enQueue(queue, newProcess(priority, burst));
        numProcesses++;
      }
      fclose(pfile);
     
      printf("\nAll Procs\n");
      printAllProcs(queue, numProcesses+1);
      // This is the initialization of the condition variables.
      for (i=0; i<numProcessors; i++)
      {
        pthread_cond_init(&timeUpdate[i], NULL);
        pthread_mutex_init(&amIDone[i], NULL);
      }
            
      pthread_create(&fcfsThread, NULL, fcfs, NULL);
      pthread_create(&rrThread, NULL, roundRobin, NULL);
      pthread_create(&srtfThread, NULL, srtf, NULL);
      pthread_create(&sjfThread, NULL, sjf, NULL);
      pthread_create(&priQueueThread, NULL, priQueue, NULL);
    
      fprintf(stdout, "created threads, pausing while they init...\n");
      pthread_yield();
    
      allDone = false;
      while (allDone == false)
      {
        //printf("i'm in main's loop\n");
        pthread_mutex_lock(&timeSem);
        masterTime++;
    
        pthread_mutex_lock(&queueSem);
        incrementWaitTimes(queue);
        pthread_mutex_unlock(&queueSem);
    
        allDone = true;
        for (i=0; i<numProcessors; i++)
        {
          if(pthread_mutex_trylock(&amIDone[i]) != 0)
          {
    	//printf("still unlocked %d\n", i);
    	allDone = false;
          }
          
        }
    
        if (allDone)
        {
          fprintf(stdout, "all processes are done...\n");
        }
        
        for (i=0; i<numProcessors; i++)
        {
          pthread_cond_signal(&timeUpdate[i]);
        }
    
        pthread_mutex_unlock(&timeSem);
        pthread_yield();
    
      }
    
      pthread_join(fcfsThread, NULL);
      pthread_join(rrThread, NULL);
      pthread_join(srtfThread, NULL);
      pthread_join(sjfThread, NULL);
      pthread_join(priQueueThread, NULL);
    
      printf("\nAll Procs\n");
      printAllProcs(queue, numProcesses+1);
    
      return 0;
    }
    
    void *fcfs()
    {
      struct nodeType *p;
      pthread_mutex_lock(&amIDone[0]);
      pthread_mutex_lock(&queueSem);
      p = deQueue(queue);
      pthread_mutex_unlock(&queueSem);
     
      while (p != NULL)
      {
        printf("i'm in fcfs\n");
        pthread_cond_wait(&timeUpdate[0], &randoSem);    
    
        pthread_mutex_lock(&timeSem);
    
        p->timeLeft--;
        pthread_mutex_lock(&outputSem);
        printProcInfo(p);
        pthread_mutex_unlock(&outputSem);
        
        if (p->timeLeft == 0)
        {
          pthread_mutex_lock(&queueSem);
          enQueue(queue, p);
          // TODO:  dequeue a process
          p = deQueue(queue);
          pthread_mutex_unlock(&queueSem);
        }
    
        pthread_mutex_unlock(&timeSem);
        pthread_cond_signal(&timeUpdate[0]);
      }
    
      pthread_mutex_unlock(&amIDone[0]);
      printf("fcfs  is done\n");
      pthread_exit(0);
    }
    
    void *roundRobin()
    {
      // TODO:  Implement a round robin scheduler.  This is similar to fcfs above, but you
      // need to track how many ticks the current process has consumed, and how many are left
      // in the "quanta".
      struct nodeType *p;
      int timeOnCPU = 0;
      pthread_mutex_lock(&amIDone[1]);
      pthread_mutex_lock(&queueSem);
      p = deQueue(queue);
      pthread_mutex_unlock(&queueSem);
      
      // debug message if you want it...
      //fprintf(stdout, "In processor 1, working on process %d.\n", p->PID);
    
      // as long as I didn't dequeue a NULL pointer, run...
      while (p != NULL)
      {
        // wait for the clock signal from the main thread...
        printf("i'm in rr\n");
        pthread_cond_wait(&timeUpdate[1], &randoSem);    
    
        pthread_mutex_lock(&timeSem);
    
        //printf("i got a process %d,  %d\n", masterTime, p->totalWait);
        p->timeLeft--;
        timeOnCPU++;
        pthread_mutex_lock(&outputSem);
        printProcInfo(p);
        pthread_mutex_unlock(&outputSem);
        
        // if my process is done, put it back on the ready queue and dequeue another
        if (p->timeLeft == 0)
        {
          pthread_mutex_lock(&queueSem);
          enQueue(queue, p);
          // TODO:  dequeue a process
          p = deQueue(queue);
          pthread_mutex_unlock(&queueSem);
        }
        
        //if the process is over the time quantum put it back and grab another
        if(timeOnCPU >= quantum)
        {
          pthread_mutex_lock(&queueSem);
          enQueue(queue, p);
          p = deQueue(queue);
          timeOnCPU = 0;
          pthread_mutex_unlock(&queueSem);
        }
    
        pthread_mutex_unlock(&timeSem);
        pthread_cond_signal(&timeUpdate[1]);
      }
    
      pthread_mutex_unlock(&amIDone[1]);
      printf("rr is done\n");
      pthread_exit(0);
    }
    
    void *srtf()
    {
      struct nodeType *p;
      pthread_mutex_lock(&amIDone[2]);
      pthread_mutex_lock(&queueSem);
      p = shortestTimeLeft(queue);
      pthread_mutex_unlock(&queueSem);
      
      // debug message if you want it...
      //fprintf(stdout, "In processor 1, working on process %d.\n", p->PID);
    
      // as long as I didn't dequeue a NULL pointer, run...
      while (p != NULL)
      {
        // wait for the clock signal from the main thread...
        printf("i'm in srtf\n");
        pthread_cond_wait(&timeUpdate[2], &randoSem);    
        pthread_mutex_lock(&timeSem);
    
        //printf("i got a process %d,  %d\n", masterTime, p->totalWait);
        p->timeLeft--;
        pthread_mutex_lock(&outputSem);
        printProcInfo(p);
        pthread_mutex_unlock(&outputSem);
        
        // if my process is done, put it back on the ready queue and dequeue another
        if (p->timeLeft == 0)
        {
          pthread_mutex_lock(&queueSem);
          enQueue(queue, p);
          // TODO:  dequeue a process
          p = shortestTimeLeft(queue);
          pthread_mutex_unlock(&queueSem);
        }
        
        pthread_mutex_unlock(&timeSem);
        pthread_cond_signal(&timeUpdate[2]);
      }
    
      pthread_mutex_unlock(&amIDone[2]);
      printf("srtf  is done\n");
      pthread_exit(0);
    }
    
    void *sjf()
    {
      struct nodeType *p;
      pthread_mutex_lock(&amIDone[3]);
      pthread_mutex_lock(&queueSem);
      p = shortestBurst(queue);
      pthread_mutex_unlock(&queueSem);
      
      // debug message if you want it...
      //fprintf(stdout, "In processor 1, working on process %d.\n", p->PID);
    
      // as long as I didn't dequeue a NULL pointer, run...
      while (p != NULL)
      {
        // wait for the clock signal from the main thread...
        printf("i'm in sjf\n");
        pthread_cond_wait(&timeUpdate[3], &randoSem);    
        pthread_mutex_lock(&timeSem);
    
        //printf("i got a process %d,  %d\n", masterTime, p->totalWait);
        p->timeLeft--;
        pthread_mutex_lock(&outputSem);
        printProcInfo(p);
        pthread_mutex_unlock(&outputSem);
        
        // if my process is done, put it back on the ready queue and dequeue another
        if (p->timeLeft == 0)
        {
          pthread_mutex_lock(&queueSem);
          enQueue(queue, p);
          // TODO:  dequeue a process
          p = shortestBurst(queue);
          pthread_mutex_unlock(&queueSem);
        }
        
        pthread_mutex_unlock(&timeSem);
        pthread_cond_signal(&timeUpdate[3]);
      }
    
      pthread_mutex_unlock(&amIDone[3]);
      printf("sjf  is done\n");
      pthread_exit(0);
    }
    
    void *priQueue()
    {
      struct nodeType *p;
      pthread_mutex_lock(&amIDone[4]);
      pthread_mutex_lock(&queueSem);
      p = highestPriority(queue);
      pthread_mutex_unlock(&queueSem);
      
      // debug message if you want it...
      //fprintf(stdout, "In processor 1, working on process %d.\n", p->PID);
    
      // as long as I didn't dequeue a NULL pointer, run...
      while (p != NULL)
      {
        // wait for the clock signal from the main thread...
        printf("i'm in pri\n");
        pthread_cond_wait(&timeUpdate[4], &randoSem);    
        pthread_mutex_lock(&timeSem);
    
        //printf("i got a process %d,  %d\n", masterTime, p->totalWait);
        p->timeLeft--;
        pthread_mutex_lock(&outputSem);
        printProcInfo(p);
        pthread_mutex_unlock(&outputSem);
        
        // if my process is done, put it back on the ready queue and dequeue another
        if (p->timeLeft == 0)
        {
          pthread_mutex_lock(&queueSem);
          enQueue(queue, p);
          // TODO:  dequeue a process with the highest priority
          p = highestPriority(queue);
          pthread_mutex_unlock(&queueSem);
        }
        
        pthread_mutex_unlock(&timeSem);
        pthread_cond_signal(&timeUpdate[4]);
      }
    
      pthread_mutex_unlock(&amIDone[4]);
      printf("pri  is done\n");
      pthread_exit(0);
    }

  2. #2
    Registered User
    Join Date
    Nov 2009
    Posts
    4
    where are you unlocking the lock obtained below in the main function

    for (i=0; i<numProcessors; i++)
    {
    if(pthread_mutex_trylock(&amIDone[i]) != 0)
    {
    //printf("still unlocked %d\n", i);
    allDone = false;
    }

    }

    there may be some possible race conditions in your code as you are locking a lot of mutexes. one possible way to check this quickly is to attach gdb to the process and see
    what each of your thread is doing when your program get stuck...
    hope it helps

Popular pages Recent additions subscribe to a feed