2012-05-08 12 views
2

プログラムは、渡された引数に基づいてx量のスレッドを作成することになっています。 argv [1]はメインがスリープすると想定される量、argv [2]はプロペッサスレッドの数、argv [3]はコンシューマスレッドの数です。プログラムは正常にコンパイルされ、実行するために使用しているコマンドはプログラム10 1 1です。Segfaultの原因を見つけることができません

私は今このコードを注視していますが、セグメンテーション違反の原因を突き止めることはできません。たぶん、目の第二のセットはそれを素早く選ぶことができるでしょう。

#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

あなたは、コードをデバッグがありますか?おおよそどこで失敗するのですか? (btw、+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 

は、バックトレースをダンプする必要があります。どのラインがsegfaultedであるかを正確に確認できます。

0

gcc -g program.c -lpthread その後、 gdb a.out セットブレークポイント としてb main start として、-gを使用してプログラムをコンパイルして、ステップ実行によってステップのためsを使用して、それが落ちている場所を確認します。誰かがすでに生産機能も

ポインタunsigned int *seed;を未初期化していることを述べたように

このプログラム(insert_itemのスレッドを実行する前に、コンテキスト切り替えた場合にどのような関数insert項目、のように通常のロック解除の問題とともに、それに関連するlost wake-up problemを持っていますplaced++

関連する問題