Я работаю над проектом, который в основном является производителем-потребителем с условиями 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. Это также происходит с потоками производителя.
Спасибо.