【问题标题】:Segmentation Fault - Producer Consumer分段错误 - 生产者消费者
【发布时间】:2017-03-15 22:10:04
【问题描述】:

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

#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

【问题讨论】:

  • 您正在创建无限多的线程。准确地说,每次迭代两次。
  • 但我得到的错误是在函数调用@StoryTeller 1 或 2 次之后
  • 不,您在看到输入大约两次后才知道。线程创建可以比这快得多。这是你的程序的一个大错误。
  • 为什么prodcons缺少return语句?
  • 您需要提供一个指向线程过程的函数指针,而您的代码调用这些函数 (cons()) 并将它们的结果用作指向线程函数的指针。 cons 和 prod 都不返回任何使返回值未定义的东西。当 pthread_create 使用这样的函数指针启动一个线程时,它只会崩溃。

标签: c producer-consumer producer


【解决方案1】:

您有多个严重的错误:

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

【讨论】:

  • 谢谢你!知道了,我没有正确使用函数格式!。
  • @GunjanRaval 请注意,您需要解决上述所有问题。这些不是一些小的挑剔,但它们都是严重的错误。
【解决方案2】:

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

【讨论】:

  • 但是我想让这些线程无限运行,那我该怎么办呢?
  • 覆盖pthread_t变量是没有问题的,它只是某种整数来识别线程。真正的问题是pthread_create(..) 中的函数调用。
【解决方案3】:

由于buffer 数组,您的段错误很确定。您正在使用最多 5 个位置的代码中定义大小为 1 及更高版本的数组。

您将其定义为:

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

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

然后你将索引它以 BUFFER_SIZE 为模:

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

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

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

【讨论】:

    猜你喜欢
    • 2018-02-05
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    相关资源
    最近更新 更多