简体   繁体   English

如何使用pthread,pthread_exit将*转换为double / float

[英]How to convert * to double/float with pthread, pthread_exit

I need to create a program which calculates recursion (for certain sequence). 我需要创建一个程序来计算递归(对于某些序列)。 When I use int and decleare a recursion, that calculates values without floating numbers (like fibonacci sequence, which returns only neutral numbers) it works. 当我使用int并清除一个递归时,它将计算不带浮点数的值(例如fibonacci序列,该值仅返回中性数),它可以工作。 However, when trying to use sequences based on divison (with floating numbers) it displays an error as below: 但是,当尝试使用基于除法的序列(带有浮点数)时,会显示如下错误:

error: cannot convert to a floating type pthread_exit((void*)(float)wynik; 错误:无法转换为浮动类型pthread_exit((void *)(float)wynik;

How should I change the code (or actually a function *ciag, because problem is with that one), that it will accept floating numbers? 我应该如何更改代码(或者实际上是一个* ciag函数,因为那是问题所在),使其可以接受浮点数?

Function which works fine (with int) 正常工作的函数(带有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);
}

And the one I have problem with (with float, but same happens when I try to use double) 我遇到的问题(使用浮点数,但是当我尝试使用double时也会发生同样的情况)

    #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;
}

You cannot directly convert a float to a void * or vice-versa. 您不能将float直接转换为void * ,反之亦然。

The cleanest way to do this is to allocate space for a float somewhere -- either from the heap or on the caller's stack -- and have the thread function store the float value into the pointed-to variable ( float * is easily convertible to/from void * ). 做到这一点的最干净的方法是在某个地方(从堆或在调用者的堆栈上)为float分配空间,并让线程函数将float值存储到指向变量中( float * 可以轻松转换为/来自void * )。 If you go this route and allocate the value on the stack, you need to make sure that the caller's stack frame remains in existence until the thread completes. 如果使用此路由并在堆栈上分配值,则需要确保在线程完成之前,调用者的堆栈帧仍然存在。

Since the function you want to call is recursive, having it as the thread function is too cumbersome. 由于您要调用的函数是递归的,因此将其作为线程函数太麻烦了。 Better to make it a separate (ordinary) function that takes an int argument and returns a float . 最好使它成为一个接受int参数并返回float的单独(普通)函数。 Then make a wrapper function that will be the target for pthread_create . 然后创建一个包装器函数,该函数将成为pthread_create的目标。

And since you also need to pass an argument int to your function, it's easiest to allocate a struct to contain both argument and return value (a union would also work since you don't really need argument and return value at the same time). 而且因为你还需要一个参数传递int到你的函数,这是最简单的分配struct ,以同时含有参数和返回值(一个union也将工作,因为你并不真的需要在同一时间参数和返回值)。 Here's a sample program that demonstrates the pattern: 这是演示该模式的示例程序:

#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;
}

One other note. 另一注。 Your code seems to suggest that pthread_join on the first thread might sometimes fail. 您的代码似乎表明第一个线程上的pthread_join有时可能会失败。 That will not happen here. 这不会在这里发生。 Though for large values of n , it may take a very long time to complete, due to the quartic nature of your function. 尽管对于n较大的值,由于函数的二次性质,可能需要很长时间才能完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM