简体   繁体   中英

C programming Segmentation fault: 11 Thread issues

Why does this error occur when I run my code? error: RUN FINISHED; Segmentation fault: 11; real time: 3s; user: 0ms; system: 0m RUN FINISHED; Segmentation fault: 11; real time: 3s; user: 0ms; system: 0m

I'm creating 10 threads where each thread is a ticket seller. There is a 10by10 array that holds the seats of the tickets. Depending on the type of the ticket-seller a person will be sold that specific seat.

Is the issue with the pthreads?

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* 
 * File:   ticketsellers.c
 * Author: iantheflyinghawaiian
 *
 * Created on July 4, 2016, 11:27 AM
 */

#include <stdio.h>
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// seller thread to serve one time slice (1 minute)

int theatre[10][10] ;

struct node
{
    int info;
    struct node *ptr;
}*front,*rear,*temp,*front1;

int count = 0;

/* Create an empty queue */
void create()
{
    front = rear = NULL;
}

/* Returns queue size */
void queuesize()
{
    printf("\n Queue size : %d", count);
}

/* Enqueing the queue */
void enq(int data)
{
    if (rear == NULL)
    {
        rear = (struct node *)malloc(1*sizeof(struct node));
        rear->ptr = NULL;
        rear->info = data;
        front = rear;
    }
    else
    {
        temp=(struct node *)malloc(1*sizeof(struct node));
        rear->ptr = temp;
        temp->info = data;
        temp->ptr = NULL;

        rear = temp;
    }
    count++;
}

/* Displaying the queue elements */
void display()
{
    front1 = front;

    if ((front1 == NULL) && (rear == NULL))
    {
        printf("Queue is empty");
        return;
    }
    while (front1 != rear)
    {
        printf("%d ", front1->info);
        front1 = front1->ptr;
    }
    if (front1 == rear)
        printf("%d", front1->info);
}

/* Dequeing the queue */
void deq()
{
    front1 = front;

    if (front1 == NULL)
    {
        printf("\n Error: Trying to display elements from empty queue");
        return;
    }
    else
        if (front1->ptr != NULL)
        {
            front1 = front1->ptr;
            printf("\n Dequed value : %d", front->info);
            free(front);
            front = front1;
        }
        else
        {
            printf("\n Dequed value : %d", front->info);
            free(front);
            front = NULL;
            rear = NULL;
        }
        count--;
}

/* Returns the front element of queue */
int frontelement()
{
    if ((front != NULL) && (rear != NULL))
        return(front->info);
    else
        return 0;
}

/* Display if queue is empty or not */
void empty()
{
     if ((front == NULL) && (rear == NULL))
        printf("\n Queue empty");
    else
       printf("Queue not empty");
}



//Ticket Seller
void * sell(char *seller_type)
{
    char seller_type1;
    seller_type1 = *seller_type;
    int i;
    i = 0;
 while (i == 0);
 {
 pthread_mutex_lock(&mutex);
 pthread_cond_wait(&cond, &mutex);
 pthread_mutex_unlock(&mutex);
 // Serve any buyer available in this seller queue that is ready
 // now to buy ticket till done with all relevant buyers in their queue
 //………………
 // Case statements for seller_types
    switch(seller_type1)
    {
        case 'H' :
            printf("Seller type: H\n");
            i = 1;
            break;
        case 'M' :
            printf("Seller type: M\n");
            i = 1;
            break;
        case 'L' :
            printf("Seller type: L\n");
            i = 1;
            break;
    }
 }
 return NULL; // thread exits
}
void wakeup_all_seller_threads()
{
 pthread_mutex_lock(&mutex);
 pthread_cond_broadcast(&cond);
 pthread_mutex_unlock(&mutex);
}
int main()
{
 int i, N;
 pthread_t tids[10];
 printf("Enter N value of Customers: ");
 scanf("%d", &N);
 printf("Number of Customers: %d", N);

 char seller_type;
 // Create necessary data structures for the simulator.
 // Create buyers list for each seller ticket queue based on the
 // N value within an hour and have them in the seller queue.
 // Create 10 threads representing the 10 sellers.
 seller_type = 'H';
 pthread_create(&tids[i], NULL, sell, &seller_type);
 seller_type = 'M';

 for (i = 1; i < 4; i++)
 pthread_create(&tids[i], NULL, sell, &seller_type);
 seller_type = 'L';
 for (i = 4; i < 10; i++)
 pthread_create(&tids[i], NULL, sell, &seller_type);
 // wakeup all seller threads
 wakeup_all_seller_threads();

 // wait for all seller threads to exit
 for (i = 0 ; i < 10 ; i++)
    pthread_join(&tids[i], NULL);
 // Printout simulation results
 //…………
 exit(0);
}

You have a data race when you pass seller_type to the newly created thread, while at the same time modify the variable in the main.

The type of the function passed to pthread_create must be: void*(*)(void*) , not the type you're using.

Function pthread_join requires a type pthread_t as the first argument, not a pointer to that type, which is what you're passing to it.

The variable i in the main isn't initialized, and is used to index the array tids , in the first pthread_create call.

All of those four problems cause undefined behavior by themselves. I suspect the last one causes the crash.

As already assumed by @2501: the culprit causing the segfault was the uninitialized variable i in main .

I took the liberty to write a minimal example for your pthread-creating, with the addition of some printf`s.

It compiles without warnings with

gcc -W -Wall threadtest.c -o threadtest -pthread

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

struct seller_type {
  char st;
  int tid;
};

void *sell(void *arg)
{
  struct seller_type *seller_type1 = arg;
  int i;
  i = 0;
  printf("thread #%d: seller_type1->st = %c\n", seller_type1->tid,
     seller_type1->st);
  // no semicolon after while()
  while (i == 0) {
    switch (seller_type1->st) {
    case 'H':
      printf("Seller type: H\n");
      i = 1;
      break;
    case 'M':
      printf("Seller type: M\n");
      i = 1;
      break;
    case 'L':
      printf("Seller type: L\n");
      i = 1;
      break;
    }
  }
  printf("thread #%d: Work done\n", seller_type1->tid);
  return NULL;
}

int main()
{
  int i = 0;
  struct seller_type *seller_type1;

  pthread_t tids[10];

  seller_type1 = calloc(10, sizeof(struct seller_type));
  // All error handling ommitted! Yes, ALL!

  seller_type1[0].st = 'H';
  seller_type1[0].tid = 0;
  pthread_create(&tids[0], NULL, sell, &seller_type1[0]);

  for (i = 1; i < 4; i++) {
    seller_type1[i].st = 'M';
    seller_type1[i].tid = i;
    pthread_create(&tids[i], NULL, sell, &seller_type1[i]);
  }

  for (i = 4; i < 10; i++) {
    seller_type1[i].st = 'L';
    seller_type1[i].tid = i;
    pthread_create(&tids[i], NULL, sell, &seller_type1[i]);
  }
  puts("All threads created");

  // wait for all seller threads to exit
  for (i = 0; i < 10; i++) {
    pthread_join(tids[i], NULL);
    printf("Thread %d joined\n", i);
  }
  puts("All threads joined");

  exit(EXIT_SUCCESS);
}

I hope you can build upon that.

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