c - 生产者消费者C中的段错误

标签 c linux segmentation-fault pthreads semaphore

我尝试在 C 和线程中使用边界缓冲区来模拟生产者消费者问题。 还使用互斥量和信号量。 预期的输出是在每次生产或消费项目时显示缓冲区的状态。 缓冲区大小固定为 10。初始缓冲区项均为 -1。当生产者向其中生产一个项目时,该项目将替换 -1。 第 0 个索引中的项目是 0,第 1 个索引是 1,依此类推......这无关紧要。 该程序询问我们要创建的生产者和消费者的数量。 生产工作正常......但不是消费。 线程 1 出现段错误。我不确定线程​​ 1 是什么。 我多次尝试使用 GDB 进行调试……没有希望。 //生产者消费者。

#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);     
}

最佳答案

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

在此调用中,pthread_create 将创建新线程并尝试在 prod[i] 中返回线程 ID 但是:

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

这些是未初始化的指针,如果你想在其中收集 threadid,你需要使用 malloc 为它们分配内存,如:

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

否则 pthread_create 会将 threadid 存储在无效内存中导致段错误

关于c - 生产者消费者C中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45912949/

相关文章:

c - 用C语言访问一个URL

c++ - 如何检查进程是否在 C++ 中运行?

mongodb - 从 channel 读取 SIGSEGV : segmentation violation

c - 为什么这个递归代码会抛出段错误?

运行 FORTRAN 代码时出现 Linux 错误,其中包含 'nullify'

C++ 段错误问题

python - 已解决 : C and Python: fill a file empty through mmap

c - C 中的计算函数/程序流程中的错误

Python C API : Call a Python function with argument(s) passed by reference

c - 在Linux上的Assembly 64中实现strcmp功能