2017-08-28 2 views
0

J'ai essayé de simuler le problème du consommateur producteur en utilisant un buffer de bounders dans C et threads. Mutex et sémaphores sont également utilisés. La sortie attendue consiste à afficher l'état du tampon chaque fois qu'un élément est produit ou consommé. La taille de la mémoire tampon est fixée à 10. Initialement, les éléments du tampon sont tous égaux à -1. Lorsqu'un producteur y crée un élément, l'élément remplace -1. L'élément dans le 0ème index est 0, le 1er index est 1 et ainsi de suite ..... ce qui n'a pas d'importance. Le programme demande le nombre de producteurs et de consommateurs que nous voulons créer. La production fonctionne bien .... mais pas la consommation. Une erreur de segmentation se produit dans le thread 1. Je ne suis pas sûr de ce qu'est le thread 1. J'ai essayé de déboguer en utilisant GDB plusieurs fois ... sans espoir. // Consommateur producteur.Erreur de segmentation dans le producteur C

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

#define TRUE 1 

int buff_size=10,i; 
int buffer[25]; 

pthread_mutex_t mutex; 
sem_t full, empty; 

int counter = 0; 
int consume_count=0; //No of Consumers created 
int produce_count=0; //No of Producers created 

void initializeData() 
{ 
    sem_init(&full, 0, 0); 
    sem_init(&empty, 0, buff_size); 
    pthread_mutex_init(&mutex, NULL); 

} 

int insert_item(int counter) 
{ 
    if (counter < buff_size) { 
     buffer[counter] = counter; 
     counter++; 
     //produce_count++; 
     return 0; 
    } 

    else { 
     printf("\n[BUFFER FULL!]"); 
     return -1; 
    } 
} 

int remove_item() 
{ 
    printf("\n[GOING TO REMOVE AN ITEM]\n"); 

    if (buffer[counter-1] != -1) { 
     buffer[counter-1] = -1; 
     counter--; 
     //consume_count++; // Commented out... 

     return 0; 
    } 

    else { 
     printf("\n[EMPTY]\n"); 
     return -1; 
    } 
} 

void *producer(void *arg) 
{ 
    int RET = 0; 

    while(TRUE) { 
     sem_wait(&empty); 
     pthread_mutex_lock(&mutex); 

    RET = insert_item(counter); 

    if (RET){ 
     printf("\nProducer Sleeping...zzZZ\n"); 
     sleep(2); 
    } 

    pthread_mutex_unlock(&mutex); 
    sem_post(&full); 

    if(!RET) 
     printf("\n[ INSERTED ]\n"); 

    printf("\n"); 

    for(i=0; i < buff_size ;i++) 
     printf("[%d] ",buffer[i]); 

    printf("\n"); 
    sleep(3); 
    } // end of while... 


} 

void *consumer(void *arg) 
{ 
    int RET = 0; 

    while(TRUE) { 
    sem_wait(&full); 
    pthread_mutex_lock(&mutex); 

    RET = remove_item(buffer); 

    if (RET){ 
     printf("\nConsumer Sleeping\n"); 
     sleep(3); 
    } 

    pthread_mutex_unlock(&mutex); 
    sem_post(&empty); 

    if(!RET) { 
     printf("\nConsumed\n"); 
     printf("\n"); 
    } 

    for(i=0 ; i < buff_size ; i++) 
     printf("%4d",buffer[i]); 

    printf("\n"); 
    sleep(2); 
    } //end of while... 

} 

void main() 
{ 
    int   produce, consume; 
    pthread_t *prod;//thread ID 
    pthread_t *cons;//thread ID 

    printf("\nEnter the no of producers: "); 
    scanf("%d",&produce); 
    printf("\nEnter the no of consumers: "); 
    scanf("%d",&consume); 
    putchar('\n'); 

    for (i=0; i < buff_size; i++) 
     buffer[i] = -1; 

    for (i=0; i < buff_size; i++) 
     printf("[%d] ", buffer[i]); 

    printf("\n"); 

    initializeData(); 

    for (i = 0; i < produce; i++) 
     { 
      pthread_create(&prod[i], NULL, producer, NULL); 
      produce_count++; 
     } 

    for (i = 0; i < consume; i++) 
     { 

      pthread_create(&cons[i], NULL, consumer, NULL); 
      consume_count++; 
      printf("AAAAA"); 
     } 
    /*for (i = 0; i < produce; i++) 
     pthread_join(producer, NULL); 

     for (i = 0; i < consume; i++) 
      pthread_join(consumer, NULL);*/ 

printf("\n===============\n[ PRODUCED: %d ]", produce_count); 
printf("\n[ CONSUMED: %d ]\n==============", consume_count);  
} 
+1

Vous appelez gcc incorrectement. L'invocation correcte est ** gcc -Wall -Werror **. –

Répondre

1
pthread_create(&prod[i], NULL, producer, NULL); 

Dans cet appel pthread_create va créer un nouveau fil et essayer de revenir id fil dans prod [i] Mais:

pthread_t *prod;//thread ID 
pthread_t *cons;//thread ID 

Ce sont des pointeurs uninitiaised, si vous voulez collecter threadids dans eux, vous devez allouer de la mémoire à eux avec malloc comme:

prod = malloc(sizeof(pthread_t) * produce); 
cons = malloc(sizeof(pthread_t) * consume); 

Sinon pthread_create stockera threadid dans la mémoire invalide menant à la faute de segment