Как конвертировать * в удвоение / плавающее с pthread, pthread_exit

Мне нужно создать программу, которая рассчитывает рекурсию (для определенной последовательности). Когда я использую 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);
}

И тот, с которым у меня проблемы (с поплавком, но то же самое происходит, когда я пытаюсь использовать 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 ответ

Вы не можете напрямую конвертировать 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, это может занять очень много времени для завершения, из-за квартальной природы вашей функции.

Другие вопросы по тегам