分段错误-生产者消费者
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 循环创建新线程并重写句柄(thread1
和 thread2
),这很可能是导致崩溃的原因。
您有多个严重错误:
- 您正在一个永恒的循环中创建线程,直到程序内存不足。你想要做的是只创建一次 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"。
这是我的基本代码,现在的问题是它运行了几个循环然后给出了分段错误。现在我知道分段错误是由于内存位置的非法 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 循环创建新线程并重写句柄(thread1
和 thread2
),这很可能是导致崩溃的原因。
您有多个严重错误:
- 您正在一个永恒的循环中创建线程,直到程序内存不足。你想要做的是只创建一次 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"。