首页 > 解决方案 > 使用多线程解析错误的参数 - c

问题描述

我正在从事一个主要是生产者-消费者的项目,在循环缓冲区上具有 pthread 条件和互斥锁。用户给出它想要多少个消费者生产者线程、随机数生成器种子、每个生产者产生多少个数字以及循环缓冲区的大小。所有这些连同条件和互斥锁都是全局变量

这是生产者线程代码

void * newProducer(void * t){
    // Get the thread id
    int * a = (int *) t;
    int id = *a;
    printf("Producer thread %d started!\n", id);

    int i;
    //Get the seed
    //seed is global vairable(Random number generator seed
    unsigned int thread_seed = seed * id;
    //Allocate memory for the array to save the numbers
    int * numbers = (int *) malloc(sizeof(int) * n);

    //Open the files
    FILE * producer_file = fopen("prods_out.txt", "w");
    if(producer_file == NULL){
        printf("ERROR: fopen failed.\n");
        exit(1);
    }
    fprintf(producer_file, "-- PRODUCER DATA --\n");

    //Produce the numbers
    for( i = 0; i < n; i++){

        numbers[i] = rand_r(&thread_seed) % 100;

        //Lock mutex
        if(pthread_mutex_lock(&mutex) < 0){
            printf("ERROR: pthread_mutex_lock failed.\n");
            exit(1);
        }
        //printf("Producer thread <%d> locked mutex\n", *id);

        //Wait until the cb has space to store numbers
        while(cb->count == cb->capacity) {
            if(pthread_cond_wait(&cond, &mutex) < 0){
                printf("ERROR: pthread_cond_wait failed\n");
                exit(1);
            }
            printf("Producer <%d> waiting\n", id);
        }

        //Put the number in the cb
        cb_push_back(cb, &numbers[i]);
       // printf("Producer <%d>: %d\n", id, numbers[i]);
        fprintf(producer_file, "Producer <%d>: %d\n", id, numbers[i]);
        count++;
        //Count is a global variable to inform the consumers that there're 
        //no more numbers to be produced

        //Tell the consumer threads that you have put a number to the cb
        if(pthread_cond_broadcast(&cond) < 0){
            printf("ERROR: pthread_cond_broadcast failed.\n");
            exit(1);
        }

        //Unlock the mutex
        if(pthread_mutex_unlock(&mutex) < 0){
            printf("ERROR: pthread_mutex_unlock failed\n");
            exit(1);
        }
        //printf("Producer thread <%d> unlocked mutex\n", *id);
    }


    // Free array
    free(numbers);
    //Close File
    fprintf(producer_file, "-- END DATA --");
    if( fclose(producer_file) != 0){
        printf("ERROR: fclose failed.\n");
        exit(1);
    }

    //THREAD EXIT
    printf("PRODUCER %d EXITS\n", id);
    pthread_exit(t);
}

这是消费者线程

void * newConsumer(void * t){
    // Get the thread id
    int * a = (int*) t;
    int id = *a;
    printf("Consumer thread %d started!\n", id);
    int  number;

    //Open the file
    FILE * consumer_file = fopen("cons_out.txt", "w");
    if(consumer_file == NULL){
        printf("ERROR: fopen failed.\n");
        exit(1);
    }
    fprintf(consumer_file, "-- CONSUMER DATA --\n");

    /*Consume integers until there are no integers left
    either to be produced or in the buffer waiting */
    while(count != p*n || cb->count != 0){
        //Lock the mutex
        //printf("Consumer <%d> has locked the mutex\n", *id);
        if (pthread_mutex_lock(&mutex) < 0){
            printf("ERROR: Could not lock mutex\n");
            exit(1);
        }

        //Wait until a producer puts an integer in the cb
        while(cb->count == 0 && end == 0){
            printf("Consumer <%d> waiting\n", id);
            if(pthread_cond_wait(&cond, &mutex) < 0){
                printf("ERROR: pthread_cond_wait failed.\n");
                exit(1);
            }
        }
        if (cb->count != 0){
            //Consume a number
            cb_pop_front(cb, &number);
           // printf("Consumer <%d>: %d\n", id, number);
            fprintf(consumer_file, "Consumer <%d>: %d\n", id, number);
        }
        //Tell the producers that you have popped a number from the cb
        if(pthread_cond_broadcast(&cond) < 0){
            printf("ERROR: pthread_cond_broadcast() failed.\n");
            exit(1);
        }
        //printf("Consumer <%d> Broadcast.\n", id);

        //Unlock the mutex
        //printf("Consumer <%d> has unlocked the mutex\n", *id);
        if(pthread_mutex_unlock(&mutex) < 0){
            printf("ERROR: pthread_mutex_unlock failed\n");
            exit(1);
        }
    }

    //Close the file stream
    fprintf(consumer_file, "-- END DATA --");
    if(fclose(consumer_file) != 0){
        printf("ERROR: fclose failed.\n");
        exit(1);
    }

    // THREAD EXIT
    printf("CONSUMER %d EXITS\n", id);
    pthread_exit(t);
}

在我运行的主要功能中

pthread_t * CONSUMERS[i] = (pthread_t*) malloc(sizeof(pthread_t) * i);
if (CONSUMERS == NULL){
    printf("ERROR: Malloc failed.\n");
    exit(1);
}


for (i = 0; i<c; i++){
    id[i] = i+1;
    pthread_create(&CONSUMERS[i], NULL, newConsumer, &id[i]);
}

我等待他们完成。我对生产者线程执行完全相同的操作。(使用不同的 pthread_t 数组和 id 数组。)

所以事情是:我在创建时放在 args 中的 id 正在改变。如果我运行 5 个消费者线程,即使我将它们的 id 设置为 1、2、3、4、5,它也会出现 65、2、3、4、68。这也发生在生产者线程上。

谢谢。

标签: cmultithreadingpthreads

解决方案


推荐阅读