Я создал простую программу, которая использует условные переменные для создания синхронизации между двумя потоками.Я получаю странный вывод, который я не могу найти решение.
В потоке генератора выдает 1000 случайных целых чисел и проверяет, являются ли они идеальными квадратами.Если число является идеальным квадратом, то оно сигнализирует о потоке монитора, который печатает квадратный корень из числа.
Проблема У меня, скорее всего, какое-то состояние гонки, потому что монитор просто не распечатывает квадратный корень, когда генератор сигнализирует.
Странная часть заключается в том, что когда я отлаживаю шаг gdb b, проходя каждый раз при изменении переменной is_square
, проблема не существует.
Любое понимание будет оценено.Я чувствую, что это связано с моим мьютексом или расположением условий.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <time.h>
int square_root;
int is_square = 0;
int done = 0;
int count = 0; //used to count how many perfect squares generator_func finds
int count1 = 0; //used to compare how many responses monitor makes to signal
pthread_mutex_t mutex;
pthread_cond_t mon;
void* generator_func(void* args){
srand(time(NULL));
int i, temp, sq;
for(i = 0; i<1000; i++){
temp = rand() % 10000;
sq = sqrt((double)temp);
if((pow(sq,2)) == temp){
pthread_mutex_lock(&mutex);
count++;
square_root = sq;
is_square = 1;
fprintf(stderr, "Square root of %d is", temp);
pthread_cond_signal(&mon);
pthread_mutex_unlock(&mutex);
}
}
pthread_mutex_lock(&mutex);
done = 1;
is_square = -1;
pthread_cond_signal(&mon);
pthread_mutex_unlock(&mutex);
}
main(){
pthread_t generator; //declare thread
pthread_mutex_init(&mutex, NULL); //initialize mutex
pthread_cond_init(&mon, NULL); //initialize condition variable
pthread_create(&generator, NULL, generator_func, NULL); //create thread
//monitor
while(done != 1){
pthread_mutex_lock(&mutex);
while(is_square == 0){
pthread_cond_wait(&mon, &mutex);
}
if(is_square == 1 && done != 1){
count1++;
fprintf(stderr, " %d\n", square_root);
is_square = 0;
}
pthread_mutex_unlock(&mutex);
}
pthread_join(generator, NULL);
printf("%d %d\n", count, count1); //shows inconsistency between generator and monitor
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&mon);
}