C 无法找到故障原因

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

程序应该根据传递给它的参数创建x个线程。argv[1]是main应该睡眠的数量,argv[2]是propucer线程的数量,argv[3]是使用者线程的数量。程序编译得很好,我用来运行它的命令是:程序10 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");
        }
    }
}
#包括
#包括
#包括
#包括
#包括
#包括“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调用,但是,我看不出该调用有什么问题。