Как конвертировать * в удвоение / плавающее с pthread, pthread_exit - PullRequest
0 голосов
/ 20 ноября 2018

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

0 голосов
/ 20 ноября 2018

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

...