我必须编写一个程序,计算前10个术语的系列(对不起我的语言,这是我第一次用英语谈论数学),由公式(x ^ i)/ i给出! 。所以,基本上它是微不足道的。但是,有一些特殊要求。每个单独的术语都要由单独的线程计算,每个术语都是并发的。然后他们都将结果保存到名为 result 的公共变量中。之后,必须通过主线程添加它们,这将显示最终结果。所有这些都使用pthreads和互斥量。
这就是我遇到问题的地方。我正在考虑使用表来存储结果,但老师告诉我,这不是正确的解决方案,因为那时我不必使用互斥锁。任何想法做什么以及如何同步它?我对pthread和互斥体完全不熟悉。
这是我到现在为止所得到的。我还在努力,所以它目前还没有工作,它只是一个程序的计划,我想添加互斥锁。我希望这不是全部错。 ; P
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
int number = 0;
float result = 0;
pthread_mutex_t term_lock;
pthread_mutex_t main_lock;
int save = 0; //condition variable
int factorial(int x) {
if(x==0 || x==1)
return 1;
return factorial(x-1)*x;
}
void *term(void *value) {
int x = *(int *)value;
float w;
if(save == 0) {
pthread_mutex_lock(&term_lock);
w = pow(x, number)/factorial(number);
result = w;
printf("%d term of series with x: %d is: %f\n", number, x, w);
number++;
save = 1;
pthread_mutex_unlock(&term_lock);
}
return NULL;
}
int main(void) {
int x, i, err = 0;
float final = 0;
pthread_t threads[10];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
printf("Get X: \n");
scanf("%d", &x);
for(i=0; i<10; i++)
{
err = pthread_create(&threads[i], &attr, (void *)term, &x);
if(err) {
printf("Error creating threads.\n");
exit(-1);
}
}
i = 0;
while (number <= 10) {
//printf("While Result: %f, final %f\n", result, final); - shows that it's infinite loop
if(save) {
pthread_mutex_lock(&main_lock);
final = final + result;
save = 0;
pthread_mutex_unlock(&main_lock);
printf("If Result: %f, final %f\n", result, final); //final == last result
}
}
return 0;
}
编辑:如果不清楚 - 我需要帮助解决方案如何将所有线程的结果存储在公共变量中并同步它。
EDIT2:可能的解决方案 - 所有线程共享的全局变量result
。返回主线程,它会被添加到一些局部变量中,所以我可以用另一个线程的结果覆盖它的值。当然它需要一些同步,所以在我在主线程中添加它之前,另一个线程不会覆盖它。你觉得怎么样?
EDIT3:我已经用我现在拥有的代码更新了代码。输出给了我8-9个术语的值(术语printf),然后程序仍在工作,什么都没有显示。评论的printf告诉我,虽然循环是无限的。局部变量final也只是结果的最后一个值。我做错了什么?
答案 0 :(得分:1)
主要线程应该是添加术语的主线程,但个别线程必须将结果写入同一个变量。我通常希望每个线程将自己的术语添加到结果中(这确实需要互斥锁),或者可能将其结果放入数组(如您所建议的),或者将其添加到共享队列(这需要互斥锁) ,甚至将其写入管道。不过,它可以通过老师的方式完成。
要解决的一个关键问题是,您需要进行明确不同的操作才能进行同步:
您不能仅使用单个同步构造,因为您无法区分计算线程和主线程。解决这个问题的一种方法是同步计算线程&#39;根据需要通过互斥锁写入,并同步那些 vs 。主线程通过信号量或条件变量读取。您也可以使用一个或多个其他互斥锁,但不能干净利落。
附加说明:
term()
函数的签名对于线程启动函数不正确。参数必须是void *
类型。我不打算为你写作业,但这是一种可行的方法:
void *
,然后将它们放回term()
函数中来提供它们的数字参数(因为它的参数应该是void *
} )。sem_wait()
)result
变量的值添加到正在运行的总计sem_post()
)同时,每个计算线程都这样做:
result
变量<强>更新强>
要为此作业使用条件变量,必须确定哪些共享状态受这些条件变量的保护,因为必须始终防止在条件变量上等待等待。
在这种情况下,所讨论的共享状态似乎很自然地涉及计算线程返回其结果的全局result
变量。该变量实际上有两种通用的互斥状态:
计算线程需要等待第一个状态,主线程需要等待(重复)第二个状态。由于线程需要等待两种不同的条件,因此需要两个条件变量。这是使用这些想法的另一种方法:
result
设置为-1
。void *
,然后将它们放回term()
函数中来提供它们的数字参数(因为它的参数应该是void *
} )。result
是否为非负数。如果是这样的话
result
变量的值添加到正在运行的总计result
设置为-1
。同时,每个计算线程都这样做:
result
的值。如果它小于零则从循环中断开result
设置为计算的术语答案 1 :(得分:0)
<?php
$a="cat";
$html=<<<HTML
<html>
<script>
var b ="$a";
document.write(b);
</script>
</html>
HTML;
echo $html;?>
在所有主题之间共享,因此您需要使用互斥锁(可能是您的老师希望看到的内容)保护它(
number
您还应该删除DETACHED状态并在打印结果之前在主程序结束时执行线程连接
答案 2 :(得分:0)
以下是我解决问题的方法:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
int number=0;
float result[10];
pthread_mutex_t lock;
int factorial(int x) {
if(x==0 || x==1)
return 1;
return factorial(x-1)*x;
}
void *term(void *value) {
int x = *(int *)value;
float w;
pthread_mutex_lock(&lock);
w = pow(x, number)/factorial(number);
printf("%d term of series with x: %d is: %f\n", number, x, w);
result[number] = w;
number++;
pthread_mutex_unlock(&lock);
return NULL;
}
int main(void) {
int x, i, err;
pthread_t threads[10];
printf("Get X: \n");
scanf("%d", &x);
for(i=0; i<=9; i++)
{
err = pthread_create(&threads[i], NULL, term, &x);
if(err) {
printf("Error creating threads.\n");
exit(-1);
}
}
for(i = 0; i < 10; i++)
{
pthread_join(threads[i], NULL);
}
i = 0;
for(i=0; i<=9; i++)
{
printf("%f\n", result[i]);
}
return 0;
}
此代码创建一个全局互斥pthread_mutex_t lock
(在这种情况下)确保任何人不会同时执行相同的代码:基本上当一个线程执行pthread_mutex_lock(&lock)
时,它禁止任何其他thread
执行该部分代码,直到“原始”线程执行pthread_mutex_unlock(&lock)
。
另一个重要的部分是pthread_join
:它的作用是强制主线程等待执行所创建的每个其他线程;这样,float result[10]
是在主线程中实际处理之前编写的(在本例中是最后一条打印指令)。
除此之外,我修复了其他用户指出的代码中的一些错误。
答案 3 :(得分:0)
如果结果是单个变量,那么一种解决方案是使用20个互斥量的数组:aMutex [20] ;.主锁定所有20个互斥锁然后启动pthreads。每个pthread [i]计算一个本地术语,等待aMutex [i],将其值存储到结果中,然后解锁aMutex [10 + i]。在main()for(i = 0; i&lt; 20; i ++){unlock aMutex [i]允许pthread [i]将其值存储到result中,然后等待aMutex [10 + i]知道结果是更新,然后将结果添加到总和。 }