正在为班级工作。将这些代码放在一起,但它给了我一些我无法解决的错误。
代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
//global variables
int N, T;
double vsum[T];
//pie function
void* pie_runner(void* arg)
{
double *limit_ptr = (double*) arg;
double j = *limit_ptr;
for(int i = (N/T)*j; i<=((N/T)*(j+1)-1); j++)
{
if(i %2 =0)
vsum[j] += 4/((2*j)*(2*j+1)*(2*j+2));
else
vsum[j] -= 4/((2*j)*(2*j+1)*(2*j+2));
}
pthread_exit(0);
}
int main(int argc, char **argv)
{
if(argc != 3) {
printf("Error: Must send it 2 parameters, you sent %s", argc);
exit(1);
}
N = atoi[1];
T = atoi[2];
if(N !> T) {
printf("Error: Number of terms must be greater then number of threads.");
exit(1);
}
for(int p=0; p<T; p++) //initialize array to 0
{
vsum[p] = 0;
}
double pie = 3;
//launch threads
pthread_t tids[T];
for(int i = 0; i<T; i++)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tids[i], &attr, pie_runner, &i);
}
//wait for threads...
for(int k = 0; k<T; k++)
{
pthread_join(tids[k], NULL);
}
for(int x=0; x<T; x++)
{
pie += vsum[x];
}
printf("pi computed with %d terms in %s threads is %k\n", N, T, pie);
}
我遇到的一个问题是阵列顶部。它需要是一个全局变量,但它一直告诉我它不是一个常量,即使我这样声明它。
任何帮助都表示赞赏,其余的代码也是如此。
**编辑:使用下面的注释更新代码后,这是新代码。我还有一些错误,并希望得到帮助处理它们。 1)警告:从指针转换为不同大小的整数[-Wpointer-to-int-cast] int j =(int)arg; 2)警告:从不同大小的整数转换为指针[Wint - to - pointer - cast] pthread_create(..........,(void *)i);
新代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
//global variables
int N, T;
double *vsum;
//pie function
void* pie_runner(void* arg)
{
long j = (long)arg;
//double *limit_ptr = (double*) arg;
//double j = *limit_ptr;
//for(int i = (j-1)*N/T; i < N*(j) /T; i++)
for(int i = (N/T)*(j-1); i < ((N/T)*(j)); i++)
{
if(i % 2 == 0){
vsum[j] += 4.0/((2*j)*(2*j+1)*(2*j+2));
//printf("vsum %lu = %f\n", j, vsum[j]);
}
else{
vsum[j] -= 4.0/((2*j)*(2*j+1)*(2*j+2));
//printf("vsum %lu = %f\n", j, vsum[j]);
}
}
pthread_exit(0);
}
int main(int argc, char **argv)
{
if(argc != 3) {
printf("Error: Must send it 2 parameters, you sent %d\n", argc-1);
exit(1);
}
N = atoi(argv[1]);
T = atoi(argv[2]);
vsum = malloc((T+1) * sizeof(*vsum));
if(vsum == NULL) {
fprintf(stderr, "Memory allocation problem\n");
exit(1);
}
if(N <= T) {
printf("Error: Number of terms must be greater then number of threads.\n");
exit(1);
}
for(int p=1; p<=T; p++) //initialize array to 0
{
vsum[p] = 0;
}
double pie = 3.0;
//launch threads
pthread_t tids[T+1];
for(long i = 1; i<=T; i++)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tids[i], &attr, pie_runner, (void*)i);
}
//wait for threads...
for(int k = 1; k<=T; k++)
{
pthread_join(tids[k], NULL);
}
for(int x=1; x<=T; x++)
{
pie += vsum[x];
}
printf("pi computed with %d terms in %d threads is %.20f\n", N, T, pie);
//printf("pi computed with %d terms in %d threads is %20f\n", N, T, pie);
free(vsum);
}
值不起作用:
./pie1 2 1
pi computed with 2 terms in 1 threads is 3.00000000000000000000
./pie1 3 1
pi computed with 3 terms in 1 threads is 3.16666666666666651864
./pie1 3 2
pi computed with 3 terms in 2 threads is 3.13333333333333330373
./pie1 4 2
pi computed with 4 terms in 2 threads is 3.00000000000000000000
./pie1 4 1
pi computed with 4 terms in 1 threads is 3.00000000000000000000
./pie1 4 3
pi computed with 4 terms in 3 threads is 3.14523809523809516620
./pie1 10 1
pi computed with 10 terms in 1 threads is 3.00000000000000000000
./pie1 10 2
pi computed with 10 terms in 2 threads is 3.13333333333333330373
./pie1 10 3
pi computed with 10 terms in 3 threads is 3.14523809523809516620
./pie1 10 4
pi computed with 10 terms in 4 threads is 3.00000000000000000000
./pie1 10 5
pi computed with 10 terms in 5 threads is 3.00000000000000000000
./pie1 10 6
pi computed with 10 terms in 6 threads is 3.14088134088134074418
./pie1 10 7
pi computed with 10 terms in 7 threads is 3.14207181707181693042
./pie1 10 8
pi computed with 10 terms in 8 threads is 3.14125482360776464574
./pie1 10 9
pi computed with 10 terms in 9 threads is 3.14183961892940200045
./pie1 11 2
pi computed with 11 terms in 2 threads is 3.13333333333333330373
./pie1 11 4
pi computed with 11 terms in 4 threads is 3.00000000000000000000
答案 0 :(得分:2)
该数组存在两个问题:第一个问题是T
不是编译时常量,如果您使用C ++进行编程则需要它。第二个是T
初始化为零,这意味着数组的大小为零,并且数组的所有索引都将超出范围。
一旦阅读T
并知道大小,就需要动态分配数组。在C语言中,您可以使用malloc
,在C ++中,您应该使用std::vector
代替。
答案 1 :(得分:2)
该代码存在许多问题。您的具体问题是,在C中,不允许在文件范围内使用可变长度数组(VLA)。
因此,如果您希望该数组是动态的,则必须声明指向它的指针并自行分配:
int N, T;
double *vsum;
然后,在设置main()
之后的T
中:
vsum = malloc (T * sizeof(*vsum));
if (vsum == NULL) {
fprintf (stderr, "Memory allocation problem\n");
exit (1);
}
记得在退出之前释放它(不是技术要求但是形式好):
free (vsum);
其他问题包括:
1 / C中没有!>
运算符,我怀疑该行应该是:
if (N > T) {
而不是:
if (N !> T) {
2 /要从命令行获取参数,请更改:
N = atoi[1];
T = atoi[2];
成:
N = atoi(argv[1]);
T = atoi(argv[2]);
3 /比较运算符为==
,而非=
,因此您需要更改:
if(i %2 =0)
成:
if (i % 2 == 0)
4 /关于没有足够参数的错误消息需要使用%d
而不是%s
,因为argc
是一个完整的类型:
printf ("Error: Must send it 2 parameters, you sent %d\n", argc-1);
在最后同意您的计算消息(并修复浮点值的%k
):
printf ("pi computed with %d terms in %d threads is %.20f\n", N, T, pie);
5 /你将一个整数指针传递给你的线程函数,但是有两个问题。
首先,您将其提取为双j
,不能用作数组索引。如果它是一个传入的整数,它应该被转回一个整数。
第二个是,在主线程更改该值以启动另一个线程之前,无法保证新线程将提取值(或者甚至开始运行其代码)。你应该直接将整数转换为void *
,而不是用整数指针搞乱。
要解决这两个问题,请在创建线程时使用它:
pthread_create (&tids[i], &attr, pie_runner, (void*)i);
这是在线程函数的开头:
int j = (int) arg;
如果您收到警告或遇到问题,可能是 ,因为您的整数和指针尺寸不兼容。在这种情况下,你可以尝试类似:
pthread_create (&tids[i], &attr, pie_runner, (void*)(intptr_t)i);
虽然我不确定会有更好的效果。
或者(虽然它有点像kludge),坚持你的指针解决方案,并确保没有竞争条件的可能性(通过传递唯一的指针线程)。
首先,将线程函数恢复为通过指针接收其值:
int j = *((int*) arg);
然后,在开始创建线程之前,您需要创建一个线程整数数组,并为每个创建的线程填充并传递该数组的正确索引(的地址):
int tvals[T]; // add this line.
for (int i = 0; i < T; i++) {
tvals[i] = i; // and this one.
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_create (&tids[i], &attr, pie_runner, &(tvals[i]));
}
除非你有这么多线程,否则不应该太繁重,因为estra数组会有问题。但是,如果您 许多线程,那么您将面临更大的问题。
6 /线程中的循环错误地递增j
而不是i
。由于这是下一节涉及的相同区域,我将在那里更正。
7 /在主要使用浮点计算时使用整数意味着您必须安排计算,以便它们不会截断分区,例如10 / 4 -> 2 where it should be 2.5
。
这意味着线程函数中的循环应该如下改变(包括像前一点一样递增i
):
for (int i = j*N/T; i <= N * (j+1) / T - 1; i++)
if(i % 2 == 0)
vsum[j] += 4.0/((2*j)*(2*j+1)*(2*j+2));
else
vsum[j] -= 4.0/((2*j)*(2*j+1)*(2*j+2));
使用所有这些更改,您会得到一个合理合理的结果:
$ ./picalc 100 101
pi computed with 100 terms in 101 threads is 3.14159241097198238535