该程序应该根据传递给它的参数创建x个线程。 argv [1]是应该睡觉的主量,argv [2]是推测线程的数量,而argv [3]是消费者线程的数量。该程序编译正常,我用来运行它的命令是:程序10 1 1 。
我已经盯着这段代码了一段时间,我似乎无法找到导致分段错误的原因。也许第二组眼睛能够快速选择它。
#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");
}
}
}
提前致谢!
答案 0 :(得分:2)
在Unix上,您可以通过转储核心并在gdb中检查核心文件来从分段错误中获得回溯。
$ ulimit -c <max core file size in 1k blocks>
$ gdb program core
gdb> bt
应该转储回溯,你可以确切地看到哪一行是segfaulted。
答案 1 :(得分:1)
在制作人中,您使用的是未初始化的指针。尝试使用malloc为它分配一些内存。我并没有准确解释它是什么,因为你把它标记为家庭作业。
也不要依赖printf语句的输出来告诉你程序在使用线程时的位置。如果你在每个printf之后显式刷新输出流,那么你几乎可以了解正确的事件序列。
答案 2 :(得分:0)
使用-g编译您的程序,为gcc -g program.c -lpthread
然后
gdb a.out
将断点设为
b main
start
然后使用s
逐步执行,看看它在哪里落下。
正如有人提到你的生成器函数有未初始化的指针unsigned int *seed;
此程序还有lost wake-up problem与之关联,以及正常的解锁问题(如在函数插入项中,如果在执行placed++
之前insert_item线程上下文切换了怎么办。)
答案 3 :(得分:0)