linuxc中的多线程
我试图计算π的值。我有多个线程正在计算PI。若我的PI和原始PI之间的差异小于0.0001,我希望向其他线程和完成线程发送信号。另一个线程(接收到信号)打印出我的PI值 我写了一个程序,但有时能正常工作,有时不能:)有人能帮我吗linuxc中的多线程,c,multithreading,ubuntu,pthreads,C,Multithreading,Ubuntu,Pthreads,我试图计算π的值。我有多个线程正在计算PI。若我的PI和原始PI之间的差异小于0.0001,我希望向其他线程和完成线程发送信号。另一个线程(接收到信号)打印出我的PI值 我写了一个程序,但有时能正常工作,有时不能:)有人能帮我吗 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #define N_THR 3 double ns=0; do
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N_THR 3
double ns=0;
double zs=0;
double moj_pi=0;
int count=0;
double diff=100;
pthread_mutex_t count_mutex;
pthread_cond_t count_cv;
void *watch_count(void *t){
pthread_mutex_lock(&count_mutex);
while (diff>=0.0001) {
pthread_cond_wait(&count_cv, &count_mutex);
printf("Calculated PI: %f.\n", moj_pi);
}
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
}
void *inc_count(void *t){
while(diff>=0.0001){
double x = ((double) rand()) / RAND_MAX;
double y = ((double) rand()) / RAND_MAX;
pthread_mutex_lock(&count_mutex);
ns++;
if (x*x + y*y <=1){
zs++;
}
moj_pi=4* zs / ns;
printf("PI: %f\n",moj_pi);
diff=M_PI - moj_pi;
if (diff<0)
diff=0-diff;
printf("Difference: %f\n",diff);
if (diff <0.0001){
pthread_cond_signal(&count_cv);
}
pthread_mutex_unlock(&count_mutex);
}
pthread_exit(NULL);
}
int main(){
int i;
pthread_t id[N_THR];
pthread_attr_t attr;
pthread_mutex_init(&count_mutex, NULL);
pthread_cond_init(&count_cv, NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&id[0], &attr, watch_count, (void *)1);
for (i=1;i<N_THR;i++)
pthread_create(&id[i], &attr, inc_count, (void *)(i+1));
for (i=0;i<N_THR;i++)
pthread_join(id[i], NULL);
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_cv);
pthread_exit(NULL);
}
#包括
#包括
#包括
#包括
#定义N_THR 3
双ns=0;
双zs=0;
双moj_pi=0;
整数计数=0;
双差=100;
pthread_mutex_t count_mutex;
pthread_cond_t count_cv;
void*watch\u计数(void*t){
pthread_mutex_lock(&count_mutex);
而(差值>=0.0001){
pthread_cond_wait(&count_cv,&count_mutex);
printf(“计算PI:%f.\n”,最小值PI);
}
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
}
void*inc_计数(void*t){
而(差值>=0.0001){
双x=((双)rand())/rand_MAX;
双y=((双)rand())/rand_MAX;
pthread_mutex_lock(&count_mutex);
ns++;
如果(x*x+y*y您正在使用来自多个线程的变量diff
,而该变量始终不受互斥保护
另外,如rand()
手册页所述:
函数rand()不是可重入的或线程安全的,因为它使用每次调用时修改的隐藏状态
再看一眼,您的问题是,diff
在循环中测试后,在锁定互斥锁之前可能会发生更改。您需要重新考虑一下锁定逻辑,以避免出现这种争用情况。您所说的“但有时工作正常,有时不正常”是什么意思?你试过什么?好吧。当Pi计算得足够近时,它调用watch_count。但有时当打印计算出的Pi时,程序不会停止,但它会继续计算Pi。我希望当Pi足够近时,程序停止。在将int
转换为void*
时要小心(当传递(void*)(I+1)
),如果它们各自的大小不匹配,这可能会成为一个问题。非常感谢。我将互斥体移到了while循环之外,现在它可以正常工作了!Thanks@JernejBevk请注意,您需要解锁实际的计算互斥锁,否则您的线程将不会并发运行(这使得线程有些毫无意义)。如果线程可能进行重叠工作,则在计算并重新锁定互斥锁后,您需要检查计算结果是否仍然有效,这样您就不会覆盖来自其他线程的更好结果。