在Pthreads中传递参数

时间:2017-01-30 12:46:43

标签: c multithreading pthreads

我试图用递归的并发程序计算pi。程序以不同的精确度计算pi。

我有一个有效的代码和一个没有代码的代码。两者之间唯一不同的部分是在创建线程时如何传递参数。两个版本都创建 np 线程并将它们传递给递归函数。他们传递的论点是结构:

struct args{double l, r, fl, fr, area; long id;};

并将它传递给函数parallel_quad:

void *parallel_quad(void *myargs) {

    struct args *args = myargs;

    /* passing the arguments to local variables */
    double l = args->l;
    double r = args->r;
    double fl = args->fl;
    double fr = args->fr;
    double area = args->area;

    /* calculating the new parameters using the 
       adaptive quadrature routine formulas */
    double m = (l+r)/2;
    double fm = f(m);
    double larea = (fl+fm)*(m-l)/2;
    double rarea = (fm+fr)*(r-m)/2;
    /* if the result is not within the given error estimate,
       continue the recursion  */   
    if (fabs((larea + rarea) - area) > epsilon) {
        args->l = l;
        args->r = m;
        args->fl = fl;
        args->fr = fm;
        args->area = larea;

        parallel_quad(args);

        args->l = m;
        args->r = r;
        args->fl = fm;
        args->fr = fr;
        args->area = rarea;

        parallel_quad(args);

    } else {
        result[args->id] += larea + rarea;
    }
}

有效的(它返回pi = 3.14159265354728356456)使用数组作为参数。看起来像这样

struct args args[np];

for (i = 0; i < np; i++){
    args[i].id = i;
    args[i].l = i * dxPerThread;
    args[i].r = args[i].l + dxPerThread;
    args[i].fl = f(args[i].l);
    args[i].fr = f(args[i].r);
    args[i].area = (f(args[i].l)+f(args[i].r))*(args[i].r-args[i].l)/2;
    pthread_create(&workerid[i], NULL, parallel_quad, &args[i]);    
}

虽然不起作用的版本(它返回pi = 3.26262338311626587384)看起来像这样

for (i = 0; i < np; i++){
    id = i;
    l = i * dxPerThread;
    r = l + dxPerThread;
    fl = f(l);
    fr = f(r);
    area = (f(l)+f(r))*(r-l)/2;
    struct args *myargs = malloc(sizeof(struct args));
    myargs->l = l;
    myargs->r = r;
    myargs->fl = fl;
    myargs->fr = fr;
    myargs->area = area;
    myargs->id = id;
    pthread_create(&workerid[i], NULL, parallel_quad, (void*)myargs);   
}

和另一个版本,返回pi = 0.12103072956898178192,看起来像这样

for (i = 0; i < np; i++){
    id = i;
    l = i * dxPerThread;
    r = l + dxPerThread;
    fl = f(l);
    fr = f(r);
    area = (f(l)+f(r))*(r-l)/2;
    struct args *myargs = malloc(sizeof(struct args));
    myargs->l = l;
    myargs->r = r;
    myargs->fl = fl;
    myargs->fr = fr;
    myargs->area = area;
    myargs->id = id;
    pthread_create(&workerid[i], NULL, parallel_quad, &myargs); 
}

并且,碰巧,3.26262338311626587384 - 0.12103072956898178192 = 3.14159265354728356456。我对C,指针和结构都很陌生,我真的不明白这里发生了什么。似乎有效的版本传递一个指向结构的地址的指针,该结构包含参数(struct args *),而另一个传递一个void-pointer(void *)。换句话说,有效的那个通过堆栈上的地址,而不起作用的地址传递指向堆的指针。有什么区别?为什么两者都没有返回相同的值?

0 个答案:

没有答案