简体   繁体   中英

Segmentation fault occurring with child pthreads

I'm currently working on custom thread scheduler project that uses pthreads in C. I have been struggling conceptually with it but am finally getting the behavior I expect to see, save for the segmentation fault.

My job is to register five child threads and schedule each one based on the order of their IDs stored in an array. What I do is call pthread_mutex_lock and tell whichever child thread that is not to be scheduled first to wait. I do some stuff to my counter to keep track of when the next child should be scheduled and after one child thread increments counter to five it should wake up other threads and do the same thing for as many times as main loop is defined.

all variables:

#define NTHREADS         5             /* Number of child threads        */
#define NUM_LOOPS  10             /* Number of local loops          */
#define SCHEDULE_INTERVAL 1            /* thread scheduling interval     */

#define errexit(code,str) fprintf(stderr,"%s: %s\n",(str),strerror(code));exit(1);

int schedule_vector[NTHREADS];        /* The thread schedule vector      */

int flag = 0;
pthread_cond_t cv;                   // condtitional variable
pthread_mutex_t mtx;               // mutex semaphore 1
int globalcounter = 0;
int currentThread;
#define TASK_LIMIT  6

here is parent thread:

int main(int argc,char *argv[])
{
  int       i;                        
  int       worker;                     
  int       ids[NTHREADS];              
  int       errcode;                 
  int       *status;                    
  int       policy;                     

  pthread_t threads[NTHREADS];        

  /* Create child threads --------------------------------------------- */
  for (worker = 0; worker < NTHREADS; worker++)
  {
    ids[worker] = worker;              

    printf("creating child thread using id %d\n", worker);

    /* Create a child thread ----------------------------------------- */
    pthread_create (                 
      &threads[worker],    
      NULL,                 
      my_thread,          
      &ids[worker]);      
    }

    /* Initialize the thread schedule vector  -------------------------- */
    schedule_vector[0] = 0;      /* First thread to be executed (0)      */
    schedule_vector[1] = 1;      /* Second thread to be exceuted (1)     */
    schedule_vector[2] = 2;      /* Third thread to be executed (2)      */
    schedule_vector[3] = 3;      /* Fourth thread to be executed (3)     */
    schedule_vector[4] = 4;      /* Fifth thread to be executed (4)      */

    signal(SIGALRM, clock_interrupt_handler);
    alarm(SCHEDULE_INTERVAL);
    printf("handler set up\n");

    /* Reap the threads as they exit ----------------------------------- */
    for (worker = 0; worker < NTHREADS; worker++)
    {
      /* Wait for thread to terminate --- */
      if (errcode=pthread_join(threads[worker],(void *) &status))
      { errexit(errcode,"pthread_join"); }

      /* Check thread's exit status and release its resources -------- */
      if (*status != worker)
      {
        fprintf(stderr,"thread %d terminated abnormally\n",worker);
        exit(1);
      }
    }

    /* The main (parent) thread terminates itself ---------------------- */
    return(0);
  }

Here is the child thread function:

void *my_thread(void * arg)
{
  long int i;                  
  long int counter;      
  int myid=*(int *) arg;  
  counter = 0;
  printf("\nI am thread #%d\n\n", myid);

  /* Main loop ------------------------------------------ */
  for (i = 0; i < NUM_LOOPS; i++)
  {

        currentThread = myid;
        pthread_mutex_lock(&mtx);
        while(myid != schedule_vector[flag]){
          pthread_cond_wait(&cv, &mtx);
        }
        counter++;
        globalcounter = counter;


    printf("Thread: %d is running ...\n", myid);
    usleep(100000);
  }
  return arg;
}

and here is my interrupt handler:

void clock_interrupt_handler(void)
{

  printf("scheduler started ++++++++++++++++++++++++++++++++++ \n");
  if (currentThread == schedule_vector[flag]) {
    printf("scheduled thread received: thread %d, and it's counter is at %d\n", currentThread, globalcounter);
    while(globalcounter < TASK_LIMIT){
    if(globalcounter == 5){
      flag++;
      pthread_cond_broadcast(&cv);
    }
    pthread_mutex_unlock(&mtx);
    alarm(SCHEDULE_INTERVAL);
    }
  } else {
    printf("unscheduled thread received, putting thread %d  with count %d to sleep...\n", currentThread, globalcounter);
    alarm(SCHEDULE_INTERVAL);

  }


}

This is the output:

scheduler started ++++++++++++++++++++++++++++++++++
scheduled thread received: thread 0, and it's counter is at 1
Thread: 0 is running ...
Thread: 0 is running ...
Thread: 0 is running ...
Thread: 0 is running ...
Segmentation fault (core dumped)

It basically repeats this behavior, but for each thread. I'd like to understand what is exactly causing the seg fault

Seems pthread_mutex_lock/pthread_mutex_unlock do not pair.

The correct code looks like

pthread_mutex_lock()
pthread_cond_broadcast()
pthread_mutex_unlock()

pthread_mutex_lock()
pthread_cond_wait()
pthread_mutex_unlock()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM