分段错误-生产者消费者

Segmentation Fault - Producer Consumer

这是我的基本代码,现在的问题是它运行了几个循环然后给出了分段错误。现在我知道分段错误是由于内存位置的非法 read/write,但我没有在该注释上使用任何指针。

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

int counter = 0;
int BUFFER_SIZE = 5;
int buffer[] = {0};
int in = 0;
int out = 0;
void *prod(char);
void *cons(void);
bool flag = true;

void main()
{   int i, j;

    pthread_t thread1, thread2; 
    do{

            flag = true;
            i = pthread_create(&thread1, NULL, prod('i'), NULL);
            flag = true;
            j = pthread_create(&thread2, NULL, cons(), NULL);

    }while(1);
}

void* prod(char a)
{
    while (flag) {
      printf("\nCounter  = %d", counter);

while (counter == BUFFER_SIZE) {
      printf("\nBusy Waiting!!!");
} 

buffer[in] = a;
in = (in + 1) % BUFFER_SIZE;
printf("\nProducer produced an item %c!",a);
counter++;
printf("\nTotal items produced = %d",counter);

flag = false;

}
}

void* cons()
{
  char a;
  while (flag) {
    printf("\nCounter  = %d",counter);
    while (counter == 0){printf("\nBusy Waiting!!!");
  } 

  a = buffer[out];
  out = (out + 1) % BUFFER_SIZE;

  counter--;

  printf("\nTotal items remaining = %d",counter);
  flag = false;
}
}

OUPUT

您应该 运行 循环一次并使用 pthread_join 等待创建的线程。 while 循环创建新线程并重写句柄(thread1thread2),这很可能是导致崩溃的原因。

您有多个严重错误:

  • 您正在一个永恒的循环中创建线程,直到程序内存不足。你想要做的是只创建一次 n 线程,然后让主程序循环(永远?)之后。
  • pthread_create(&thread1, NULL, prod('i'), NULL) 不正确,您在这里 调用 回调函数而不是提供指向它的函数指针。回调的参数需要单独传递。阅读有关 pthread_create.
  • 的手册
  • pthreads 需要 void* func (void*) 类型的函数格式。您不得使用任何其他函数格式。所以你的两个回调函数都有错误的格式。
  • 您没有对多个线程之间共享的变量使用任何形式的保护机制。您需要使用互斥锁或类似的东西。
  • stdio.h不一定是线程安全的,要看你使用的是哪个系统和C标准版本。参见 stdout thread-safe in C

由于 buffer 数组,您的段错误很可能是肯定的。您正在定义一个大小为 1 的数组,稍后在您使用最多 5 个位置的代码中。

您将其定义为:

int BUFFER_SIZE = 5;
int buffer[] = {0};

这实际上创建了一个只能容纳 1 个 int 的缓冲区(因为您使用的是只有一个值的初始化程序)。

然后你正在索引它模 BUFFER_SIZE:

buffer[in] = a;
in = (in + 1) % BUFFER_SIZE;

这将在第一次迭代后溢出 buffer(当 in 大于 0,并且您正在尝试索引未分配的位置 - 或者,更好地说,部分为 buffer).

分配的内存

您认为您没有使用指针,但实际上您在使用。在 C 中,数组索引 buffer[in] 等同于 *(buffer + in),因此您的代码实际上是 "using pointers"。