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