How to convert * to double/float with pthread, pthread_exit

548 views Asked by At

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. 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;

How should I change the code (or actually a function *ciag, because problem is with that one), that it will accept floating numbers?

Function which works fine (with 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)

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

There are 1 answers

3
Gil Hamilton On

You cannot directly convert a float to a void * or vice-versa.

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 *). 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. Then make a wrapper function that will be the target for 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). 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. 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.