C 无法找到故障原因
程序应该根据传递给它的参数创建x个线程。argv[1]是main应该睡眠的数量,argv[2]是propucer线程的数量,argv[3]是使用者线程的数量。程序编译得很好,我用来运行它的命令是:程序10 1 我已经盯着这段代码看了一段时间了,我似乎找不到导致分段错误的原因。也许第二双眼睛能很快地找到它C 无法找到故障原因,c,segmentation-fault,C,Segmentation Fault,程序应该根据传递给它的参数创建x个线程。argv[1]是main应该睡眠的数量,argv[2]是propucer线程的数量,argv[3]是使用者线程的数量。程序编译得很好,我用来运行它的命令是:程序10 1 我已经盯着这段代码看了一段时间了,我似乎找不到导致分段错误的原因。也许第二双眼睛能很快地找到它 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <semapho
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include "buffer.h"
void *producer(void *);
void *consumer(void *);
// Semaphores
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
// Buffer
int placed = 0;
buffer_item buffer[BUFFER_SIZE];
int insert_item(buffer_item item){
/* INSERT ITEM INTO BUFFER */
int z;
sem_wait(&empty);
//mutex lock
z = pthread_mutex_lock(&mutex);
if (z != 0){
return -1;
}
buffer[placed] = item;
//mutex unlock
z = pthread_mutex_unlock(&mutex);
if (z != 0){
return -1;
}
sem_post(&full);
placed++;
printf("producer produced %d\n", item);
}
int remove_item(buffer_item *item){
/* REMOVE ITEM FROM BUFFER */
int m;
placed--;
sem_wait(&full);
//mutex lock
m = pthread_mutex_lock(&mutex);
if (m != 0){
return -1;
}
buffer[placed] = -1;
//mutex unlock
m = pthread_mutex_unlock(&mutex);
if (m != 0){
return -1;
}
sem_post(&empty);
printf("consumer consumed %d\n", rand);
return 0;
}
// Main
int main(int argc, char *argv[]){
int sleepNum, pThreadNum, cThreadNum, p;
sleepNum = atoi(argv[1]);
pThreadNum = atoi(argv[2]);
cThreadNum = atoi(argv[3]);
// Initialize Semaphores & mutex
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);
// Create producer thread
pthread_t tid[pThreadNum];
int g=pThreadNum-1;
while(g >= 0){
p = pthread_create(&tid[g], NULL, producer, NULL);
g--;
}
printf("created prod thread");
// Create consumer thread
pthread_t kid[cThreadNum];
g = cThreadNum-1;
while(g >= 0){
p = pthread_create(&kid[g], NULL, consumer, NULL);
g--;
}
// Sleep for argv[0]
sleep(sleepNum);
// Destroy mutex & semaphores
sem_destroy(&empty);
sem_destroy(&full);
p = pthread_mutex_destroy(&mutex);
// Exit
exit(0);
}
// Producer
void *producer(void *param){
buffer_item rand;
unsigned int *seed;
int b;
while(1){
sleep(2);
rand = rand_r(seed);
b = insert_item(rand);
if (b < 0){
printf("Error producing item.");
}
}
}
// Consumer
void *consumer(void *param){
buffer_item rand;
int d;
while(1){
sleep(2);
d = remove_item(&rand);
if (d < 0){
printf("Error removing item");
}
}
}
#包括
#包括
#包括
#包括
#包括
#包括“buffer.h”
无效*制作人(无效*);
无效*消费者(无效*);
//信号量
扫描电镜不为空;
扫描电镜全;
pthread_mutex_t mutex;
//缓冲区
int=0;
缓冲区\项目缓冲区[缓冲区\大小];
int insert_项(缓冲区_项){
/*将项目插入缓冲区*/
intz;
sem_等待(&empty);
//互斥锁
z=pthread\u mutex\u lock(&mutex);
如果(z!=0){
返回-1;
}
缓冲区[放置]=项目;
//互斥解锁
z=pthread_mutex_unlock(&mutex);
如果(z!=0){
返回-1;
}
sem_职位(完整);
放置++;
printf(“生产商生产%d\n”,物料);
}
int删除项目(缓冲区项目*项目){
/*从缓冲区中删除项*/
int m;
放置--;
sem_等待(&full);
//互斥锁
m=pthread\u mutex\u lock(&mutex);
如果(m!=0){
返回-1;
}
缓冲区[放置]=-1;
//互斥解锁
m=pthread\u mutex\u unlock(&mutex);
如果(m!=0){
返回-1;
}
sem_post(&空);
printf(“消费者消费%d\n”,兰特);
返回0;
}
//主要
int main(int argc,char*argv[]){
int sleepNum、pThreadNum、cThreadNum、p;
sleepNum=atoi(argv[1]);
pThreadNum=atoi(argv[2]);
cThreadNum=atoi(argv[3]);
//初始化信号量和互斥
sem_init(&empty,0,缓冲区大小);
sem_init(&full,0,0);
pthread_mutex_init(&mutex,NULL);
//创建生产者线程
pthread_t tid[pThreadNum];
int g=pThreadNum-1;
而(g>=0){
p=pthread_create(&tid[g],NULL,producer,NULL);
g--;
}
printf(“创建的产品线程”);
//创建消费线程
pthread_t kid[cThreadNum];
g=cThreadNum-1;
而(g>=0){
p=pthread_create(&kid[g],NULL,consumer,NULL);
g--;
}
//argv的睡眠[0]
睡眠(sleepNum);
//销毁互斥和信号量
sem_销毁(&empty);
sem_销毁(&full);
p=pthread\u mutex\u destroy(&mutex);
//出口
出口(0);
}
//制作人
无效*生产者(无效*参数){
缓冲区项目随机数;
无符号整数*种子;
int b;
而(1){
睡眠(2);
兰德=兰德(种子);
b=插入项目(兰特);
if(b<0){
printf(“错误生成项目”);
}
}
}
//消费者
无效*使用者(无效*参数){
缓冲区项目随机数;
int d;
而(1){
睡眠(2);
d=删除项目(&rand);
if(d<0){
printf(“删除项目的错误”);
}
}
}
提前谢谢 在Unix上,通过转储core并在gdb中检查core文件,可以从分段错误中获得回溯
$ ulimit -c <max core file size in 1k blocks>
$ gdb program core
gdb> bt
$ulimit-c
$gdb计划核心
gdb>bt
应该转储回溯,并且您可以确切地看到哪一行出现故障。在生产者中,您使用的是未初始化的指针。尝试使用malloc为其分配一些内存。我没有解释到底是什么,因为你把它标记为家庭作业
另外,在使用线程时,不要依赖printf语句的输出来告诉您程序到达了哪里。如果在每次printf之后显式地刷新输出流,那么几乎可以知道事件的正确顺序。使用-g编译程序,如
gcc-g program.c-lpthread
然后
gdb a.out
将断点设置为
b main
开始
然后使用s
一步一步地执行,看看它落在哪里
正如有人已经提到的,生产者函数具有未初始化的指针无符号int*种子代码>
此外,该程序还与此相关,以及正常的解锁问题(如在函数insert item中,如果在执行placed++
之前切换了insert_item线程上下文会怎么样)这是一篇查找SEGFULTS原因的好文章
您调试过代码吗?它大约在哪里失效?(顺便说一句,使用家庭作业标签+1)我一直在添加printf,它似乎没有达到线程创建。我想知道我是否没有正确地从int main中提取参数。为什么要将其标记为C++
?代码看起来像纯C.,C++没有可变长度数组,如<代码> pthRead(tthdnUnm);代码>。除seg故障外,您还遇到了更多问题。如果两个制作人加入,第一个制作人任务在sem_post(&full)之后立即切换,会发生什么情况;?你试过valgrind吗?基于回溯,我相信错误来自于main中的atoi调用,但是,我看不出该调用有什么问题。