2016-11-14 4 views
0

コードが長すぎて読みにくいことに気付きました。セグメンテーションフォルト:マルチスレッドプログラムの実行中にコアがダンプされる

私が引数を渡し、本体の引数を構築する方法を確認できますか? 本質的には、私が "生産"機能と "消費"機能を正しく実装していれば、共有循環キューとセマフォとミューテックスを各スレッドの生成/消費に渡したいと思っています。

typedef struct circularQueue 
{ 
    int *items; 
    int *head; 
    int *tail; 
    int numProduced; 
    int numConsumed; 
} circularQueue; 

typedef struct threadArg 
{ 
    int id; 
    circularQueue *queue; 
    pthread_mutex_t *mutex; 
    sem_t *spaces; 
    sem_t *itemAvail; 
    int numItems; 
    int bufferSize; 
    int numProducer; 
    int numConsumer; 
} threadArg; 

pthread_t *producerThd; 
pthread_t *consumerThd; 

int main(int argc, char* argv[]) 
{ 
    pthread_attr_t attr; 

    // In fo to pass to thread arg 
    circularQueue *myQueue; 
    pthread_mutex_t useSharedMem; 
    sem_t spaces; 
    sem_t itemAvail; 
    int numItems; 
    int bufferSize; 
    int numProducer; 
    int numConsumer; 

    int i, j, k, l; 

    if(argc != 5) 
    { 
     printf("Enter in 4 arguments - N B P C\n"); 
     return -1; 
    } 
    numItems = atoi(argv[1]); 
    bufferSize = atoi(argv[2]); 
    numProducer = atoi(argv[3]); 
    numConsumer = atoi(argv[4]); 

    if(numItems == 0 || bufferSize == 0 || numProducer == 0 || numConsumer == 0) 
    { 
     printf("Parameters should not be 0\n"); 
     return -1; 
    } 

    // Initialize list of threads 
    producerThd = malloc(sizeof(pthread_t) * numProducer); 
    consumerThd = malloc(sizeof(pthread_t) * numConsumer); 

    // Initialize semaphores 
    sem_init(&spaces, 0, bufferSize); 
    sem_init(&itemAvail, 0, 0); 

    // Initialize mutex 
    pthread_mutex_init(&useSharedMem, NULL); 

    // Initialzie thread attributes 
    pthread_attr_init(&attr); 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 


    // Initialize queue 

    myQueue = (circularQueue*)malloc(sizeof(circularQueue)); 
    myQueue->items = (int*)malloc(sizeof(int)*bufferSize); 
    myQueue->head = myQueue->items; 
    myQueue->tail = myQueue->items; 
    myQueue->numProduced = 0; 
    myQueue->numConsumed = 0; 



    // thread arguments 
    for(i = 0; i < numProducer; i++) 
    { 
     // Initialize thraed args 
     threadArg *args = (threadArg*)malloc(sizeof(threadArg)); 
     args->queue = (circularQueue*)malloc(sizeof(circularQueue)); 
     args->mutex = &useSharedMem; 
     args->spaces = &spaces; 
     args->itemAvail = &itemAvail; 
     args->numItems = numItems; 
     args->bufferSize = bufferSize; 
     args->numProducer = numProducer; 
     args->numConsumer = numConsumer; 
     args->id = i; 
     pthread_t thisThread = *(producerThd + i); 
     pthread_create(&thisThread, &attr, produce, args); 
    } 

    for(j = 0; j < numConsumer; j++) 
    { 
     // Initialize thraed args 
     threadArg *args = (threadArg*)malloc(sizeof(threadArg)); 
     args->queue = (circularQueue*)malloc(sizeof(circularQueue)); 
     args->mutex = &useSharedMem; 
     args->spaces = &spaces; 
     args->itemAvail = &itemAvail; 
     args->numItems = numItems; 
     args->bufferSize = bufferSize; 
     args->numProducer = numProducer; 
     args->numConsumer = numConsumer; 
     args->id = j; 
     pthread_t thisThread = *(consumerThd + i); 
     pthread_create(&thisThread, &attr, consume, args); 
    } 

    for(k = 0; k < numProducer; k++) 
    { 
     pthread_join(*(producerThd+k), NULL); 
    } 

    printf("Finished waiting for producers\n"); 


    for(l = 0; l < numConsumer; l++) 
    { 
     pthread_join(*(consumerThd+l), NULL); 
    } 
    printf("Finished waiting for consumers\n"); 


    free(producerThd); 
    free(consumerThd); 
    free(myQueue->items); 
    free(myQueue); 
    sem_destroy(&spaces); 
    sem_destroy(&itemAvail); 

    fflush(stdout); 
    return 0; 
} 

は、あなたのコード内の未定義の動作の複数のソースが

+0

マルチスレッドプログラムではすべてのスレッドからコードを実行する命令がないため、スレッドのいずれかでクラッシュが発生している可能性があることを理解しているので、ここやそこで起きているとは言えません。また、未定義の振る舞いもそうである傾向があります。プログラムが処理しているデータのようなものによっては発生するかもしれないし、そうでないかもしれないので、この種のエラーがいつどこで起こるかを予測することもできません。 –

+1

[valgrind](http://www.valgrind.org)を使用するだけで問題が見つかるはずです。 –

+0

あなたの問題は、各スレッドが独自のミューテックスを持っているように見えるので、実際には互いをロックアウトしないと思います。 (そして、おそらく両方のミューテックスのpthread_mutex_initはおそらく未定義の動作です) – immibis

答えて

0

ありますありがとう、あなたはどちらかのコンパイル警告、または私はあなたがそれらを無視し、最悪の考慮を有効にせずにコンパイルされています。

  1. validItemdoubleなので、最後の指定子は%fする必要がありますので、あなたは

    printf("cid %d found this item %d as valid item %d\n", myArgs->id, thisItem, validItem); 
    

    に間違ったprintf()指定子を持っています。

  2. スレッド関数は値を返すことはありませんが、そのような関数に必要な署名であるvoid *を返すように宣言しています。

  3. main()ファンクションでmyQueueを解放して参照解除していますが、そのコードがコメントされているため、初期化していません。

また、一貫したスタイルがなく、宣言とステートメントを混在させると、コードが読みにくくなります。変数の範囲を決定することは非常に困難です。

コードを修正するだけで、他の人が読むのに役立つだけでなく、修正して問題をすばやく見つけるのに役立ちます。

+0

こんにちは、ありがとうございました。私はコードがかなり長いことに気付きました。質問を編集して、自分のコードに関する具体的な質問をします – goodday

関連する問題