我尝试使用pthreads库在C for Linux中创建一个多线程应用程序,该库使用带有N + 1个项的无限级数来近似pi。从命令行传递可变N和T.我正在使用Pi的Nilakantha近似公式。 N是求和的数字序列的上限,T是计算该总和的子线程的数量。例如,如果我运行命令" ./ pie 100 4"。父线程将创建4个索引为0到3的子线程。我有一个名为vsum的全局变量,它是一个使用malloc动态分配的双数组来保存值。所以用4个线程和100作为上限。我的程序应该计算:
Thread 0 computes the partial sum for i going from 0 to 24 stored to an element vsum[0]
Thread 1 computes the partial sum for i going from 25 to 49 stored to an element vsum[1]
Thread 2 computes the partial sum for i going from 50 to 74 stored to an element vsum[2]
Thread 3 computes the partial sum for i going from 75 to 99 stored to an element vsum[3]
每个线程进行计算后。主线程将通过将所有数字从vsum [0]加到vsum [T-1]来计算总和。
我刚刚开始了解线程和进程。任何帮助或建议将不胜感激。谢谢。
到目前为止我编写的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
double *vsum;
int N, T;
void *PI(void *sum) //takes param sum and gets close to pi
{
int upper = (int)sum;
double pi = 0;
int k = 1;
for (int i = (N/T)*upper; i <= (N/T)*(upper+1)-1; i++)
{
pi += k*4/((2*i)*(2*i+1)*(2*i+2));
if(i = (N/T)*(upper+1)-1)
{
vsum[upper] = pi;
}
k++;
}
pthread_exit(0);
}
int main(int argc, char*argv[])
{
T = atoi(argv[2]);
N = atoi(argv[1]);
if (N<T)
{
fprintf(stderr, "Upper bound(N) < # of threads(T)\n");
return -1;
}
int pie = 0;
pthread_t tid[T]; //thread identifier
pthread_attr_t attr; //thread attributes
vsum = (double *)malloc(sizeof(double));//creates dyn arr
//Initialize vsum to [0,0...0]
for (int i = 0; i < T; i++){
{
vsum[i] = 0;
}
if(argc!=2) //command line does not give proper # of values
{
fprintf(stderr, "usage: commandline error <integer values>\n");
return -1;
}
if (atoi(argv[1]) <0) //if its is negative/sum error
{
fprintf(stderr, "%d must be >=0\n", atoi(argv[1]));
return -1;
}
//CREATE A LOOP THAT MAKES PARAM N #OF THREADS
pthread_attr_init(&attr);
for(int j =0; j < T;j++)
{
int from = (N/T)*j;
int to = (N/T)*(j+1)-1;
//CREATE ARRAY VSUM TO HOLD VALUES FOR PI APPROX.
pthread_create(&tid[j],&attr,PI,(void *)j);
printf("Thread %d computes the partial sum for i going from %d to %d stored to an element vsum[%d]\n", j, from, to, j);
}
//WAITS FOR THREADS TO FINISH
for(int j =0; j <T; i++)
{
pthread_join(tid[j], NULL);
}
//LOOP TO ADD ALL THE vsum array values to get pi approximation
for(int i = 0; i < T; i++)
{
pie += vsum[i];
}
pie = pie +3;
printf("pi computed with %d terms in %d threads is %d\n",N,T,pie);
vsum = realloc(vsum, 0);
pthread_exit(NULL);
return 0;
}
这是错误我没看到我参加我的计划:我在这里缺少什么?
^
pie.c:102:1: error: expected declaration or statement at end of input
}
当我尝试运行我的程序时,我得到以下内容:
./pie.c: line 6: double: command not found
./pie.c: line 7: int: command not found
./pie.c: line 8: int: command not found
./pie.c: line 10: syntax error near unexpected token `('
./pie.c: line 10: `void *PI(void *sum) //takes param sum and gets close to pi'
答案 0 :(得分:1)
我没有查看代码的逻辑,但我看到了以下编程错误。
更改
pthread_create(&tid[j],&attr,PI,j);
到
pthread_create(&tid[j],&attr,PI,(void *)j);
pthread_create()
将第4个参数作为void *
传递给线程函数。
同时修复线程函数PI
以将传递的参数用作int
,如
void *PI(void *sum) //takes param sum and gets close to pi
{
int upper = (int)sum; //don't use `atoi` as passed param is int.
...
//your existing code
}
第3个错误是行
realloc(vsum, 0);
通过传递0重新分配,您实际上只是释放vsum
,因此您可以使用free(vsum)
。如果你确实想重新分配,你应该使用函数返回的新分配的内存,如vsum = realloc(vsum, 0);
答案 1 :(得分:0)
pthread的语法是
pthread_create(threadId,threadAttribute,callingMethodName,调用方法的参数);
例如:
void printLetter( void *p)
{
int i=0;
char c=(char *)p;
while (i<10000)
{
printf("%c",c);
}
}
int main()
{
pthread_t thread_id;
char c='x';
pthread_create (&thread_id, NULL, &printLetter, &c);
pthread_join (thread_id, NULL);
return 0;
}
}