gpt4 book ai didi

c - 带有条件变量的简单生成器监控程序

转载 作者:行者123 更新时间:2023-12-04 06:06:57 28 4
gpt4 key购买 nike

我创建了一个简单的程序,它使用条件变量在两个线程之间创建同步。我得到一个奇怪的输出,我似乎找不到解决方案。

程序做的是 ,在生成器线程中,生成 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);
}

最佳答案

小心使用条件变量。这里有一个大陷阱,它可能发生在您身上:如果在条件变量上调用信号但没有线程在等待它,信号就会丢失 .

我的猜测是,您的主线程无法在生成器线程调用信号时到达等待调用(在主线程到达等待时它可能会多次调用它),这就是您丢失一些值的原因.

调试器不是检查这一点的好方法,因为它往往会使这些微妙的计时错误消失。

其他问题:

  • 生成器可能会在主线程到达 while 之前完成。
  • done 应该是 volatile 因为它是跨线程修改的。
  • 关于c - 带有条件变量的简单生成器监控程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8245888/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com