Неправильный анализ аргумента с многопоточностью - c - PullRequest
0 голосов
/ 08 июня 2018

Я работаю над проектом, который в основном является производителем-потребителем с условиями 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]);
}

и жду их завершения.я делаю то же самое для потоков производителей. (С массивом diffrent pthread_t и массивом id.)

Так что дело в том, что идентификатор, который я помещаю в аргументы при создании, изменяется.Если я запускаю 5 потребительских потоков, даже если я идентифицирую их идентификаторы как 1, 2, 3, 4, 5, получается 65, 2, 3, 4, 68. Это также происходит с потоками производителя.

Спасибо.

...