【问题标题】:How to convert * to double/float with pthread, pthread_exit如何使用 pthread、pthread_exit 将 * 转换为 double/float
【发布时间】:2019-04-23 00:44:04
【问题描述】:

我需要创建一个计算递归的程序(对于某些序列)。当我使用 int 并取消递归时,它可以计算没有浮点数的值(如斐波那契数列,它只返回中性数字)它可以工作。但是,当尝试使用基于除法(带有浮点数)的序列时,它会显示如下错误:

错误:无法转换为浮点类型 pthread_exit((void*)(float)wynik;

我应该如何更改代码(或者实际上是一个函数 *ciag,因为那个有问题),它会接受浮点数?

可以正常工作的函数(使用 int)

int* fibo(int n){

   int wynik;
   int* n1;
   if (n==0) wynik=0;
   else if (n==1) wynik=1;
   else wynik =(int)fibo((int)(n-1))+(int)fibo((int)(n-2));
   return (int*)wynik;
   pthread_exit((void*)wynik);
}

还有我遇到的问题(使用浮点数,但当我尝试使用双精度时也会发生同样的情况)

    #include <unistd.h>

#include <pthread.h>
#include <stdio.h>

#define COUNT 2

float *ciag(int n) {
    float wynik;

    if(n == 0)
        wynik = -1;
    else
        wynik = ((float)ciag(n - 1)*(n + 1))/(float)ciag(n - 1)*(float)ciag(n - 1)*(float)ciag(n - 1);

    return(float *)wynik;
    pthread_exit((void *)wynik);
}

void *drugi_watek(void* wynik) {
    int i = 1;  

        while(i == 0) {
        printf("#");
        fflush(stdout);
        usleep(300000);
        pthread_exit((void*)wynik);
    }
}

int main() {
    pthread_t watek_1, watek_2;
    int n;
    float wynik;
    printf("Podaj numer ciagu: ");
    scanf("%d", &n); 

    pthread_create(&watek_1, NULL,(void*)&ciag, n);
    pthread_create(&watek_2, NULL, &drugi_watek, NULL);

    if(!pthread_join(watek_1,(void**)&wynik))
    {
    pthread_cancel(watek_2);
    }

    printf("Element numer %f ciagu: %f\n", &n, &wynik);


    return 0;
}

【问题讨论】:

    标签: c unix pthreads pthread-join pthread-exit


    【解决方案1】:

    您不能直接将float 转换为void *,反之亦然。

    最干净的方法是在某处为float分配空间——无论是从堆上还是在调用者的堆栈上——并让线程函数将float值存储到指向变量中( float * 很容易与void * 相互转换)。如果你走这条路线并在堆栈上分配值,你需要确保调用者的堆栈帧一直存在,直到线程完成。

    由于你要调用的函数是递归的,把它作为线程函数太麻烦了。最好让它成为一个单独的(普通)函数,它接受一个int 参数并返回一个float。然后创建一个包装函数,作为pthread_create 的目标。

    而且由于您还需要将参数int 传递给您的函数,因此分配struct 来包含参数和返回值是最简单的(union 也可以工作,因为您并不真的需要参数并同时返回值)。这是一个演示该模式的示例程序:

    #include <pthread.h>
    #include <stdio.h>
    
    static float ciag(int n)
    {
        float wynik;
    
        if(n == 0)
            wynik = -1;
        else
            wynik = (ciag(n - 1)*(n + 1))/ciag(n - 1)*ciag(n - 1)*ciag(n - 1);
    
        return wynik;
    }
    
    typedef struct {
        int i;
        float f;
    } if_t;
    
    static void *ciag_thread(void *vp)
    {
        if_t *ifp = vp;
        // Obtain argument from the structure and put the result back into the structure
        ifp->f = ciag(ifp->i);
        return vp;
    }
    
    int main()
    {
        pthread_t watek_1;
    
        int n = 4;
    
        // Obtain n however you like. Then place argument into structure allocated 
        // on the stack
        if_t arg;
        arg.i = n;
    
        // Pointer to structure is implicitly convertible to (void *)
        pthread_create(&watek_1, NULL, ciag_thread, &arg);
        pthread_join(watek_1, NULL);
        printf("Thread returned %f\n", arg.f);
        return 0;
    }
    

    另一个注释。您的代码似乎表明第一个线程上的 pthread_join 有时可能会失败。这不会发生在这里。尽管 n 的值很大,但由于函数的四次性质,可能需要很长时间才能完成。

    【讨论】:

    • 这就是我的意思。在计算序列之前,第二个线程应该显示“#”。现在它工作正常:) 但是 - 我如何将它连接到第二个线程(显示“#”并在计算序列时关闭)?谢谢你的帮助
    • 试过这种方式...pastebin.com/qxb7ukuA 但他们仍然不想联系和一起工作
    • 两个选项:(1)让你的第二个线程在它的循环中观察一个标志变量(从变量为零开始,当你的第一个线程完成时将其设置为 1);让第二个线程在看到标志集时退出循环[此方法最好,因为它使第二个线程的关闭有序]; (2) 当第一个线程退出时,只需在第二个线程上使用pthread_cancel
    猜你喜欢
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多