2012-05-08 109 views
2

程序应该根据传递给它的参数创建x个线程。 argv [1]是main应该休眠的数量,argv [2]是propucer线程的数量,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

你有没有调试的代码?它大约在哪里失败? (顺便说一句,+1使用作业标签) – Kiril

+0

我一直在printf的添加,它似乎并没有达到创建线程。我想知道如果我不从int main中正确地拉参数。 – Bigby

+2

你为什么给它加上'C++'标签?代码看起来像纯C.同样,C++没有像'pthread_t tid [pThreadNum];'这样的可变长度数组。 –

回答

1

在制片人使用的是未初始化的指针。尝试使用malloc分配一些内存。我没有解释到底是什么,因为你把这个标记为家庭作业。

而且不依赖于从printf语句输出来告诉你该程序使用了线程时。它有助于在每次printf后显式清空输出流,那么您几乎可以了解正确的事件序列。

2

在Unix上,你可以转储核心和追问在gdb的核心文件得到分割故障回溯。

$ ulimit -c <max core file size in 1k blocks> 
$ gdb program core 
gdb> bt 

应该转储回溯,并且您可以看到确切的哪条线被分割。

0

与-g编译你的程序,如gcc -g program.c -lpthread 然后 gdb a.out 设置断点为 b main start 然后一步执行使用s的一步,看看它正在下降。

正如有人已经提到,你的生产函数初始化指针unsigned int *seed;

也是这个程序有与之相关联的,与正常解锁问题一起(如函数插入项目,在做之前,如果insert_item线程上下文交换lost wake-up problemplaced++