I tried running your code and came across a few surprises:
printf("The number is: %d\n", finalFib);
This line has a small error: %d means printf expects an int , but a long int is passed. On most platforms, this is the same thing, or will have the same behavior anyway, but pedantically (or if you just want to stop the warning to get up, which is also a very noble ideal), you should use %ld instead, which will expect a long int .
Your fib function, on the other hand, seems dysfunctional. While checking it on my car, it does not fall, but it gives 1047 , which is not a Fibonacci number. If you look closely, it seems that your program is incorrect in several respects:
void *fib(void *fibToFind) { long retval;
Always watch for compiler warnings: when you get them, usually you really do something suspicious.
Perhaps you should revise the algorithm a bit: right now, all your function returns the sum of two undefined values, so I got 1047 earlier.
Implementing the Fibonacci package using a recursive algorithm means you need to call the function again. As others have noted, this is a pretty inefficient way to do this, but it's easy, so I think all computer science teachers use it as an example.
A regular recursive algorithm is as follows:
int fibonacci(int iteration) { if (iteration == 0 || iteration == 1) return 1; return fibonacci(iteration - 1) + fibonacci(iteration - 2); }
I donโt know to what extent you should use threads - just run the algorithm on the secondary thread or create new threads for each call? Suppose to be the first at the moment, as it is much more straightforward.
Integer numbers for pointers and vice versa is bad practice because if you are trying to look at things at a higher level, they should be different. Integers do the math, and pointers resolve memory addresses. This happens because they are represented identically, but in fact you should not do this. Instead, you may notice that the function called to start your new thread takes the void* argument: we can use it to pass both where the input is and where the output will be.
Thus, based on my previous fibonacci function, you can use this code as the main thread program:
void* fibonacci_offshored(void* pointer) { int* pointer_to_number = pointer; int input = *pointer_to_number; *pointer_to_number = fibonacci(input); return NULL; }
It expects a pointer to an integer and takes its input from it, then writes its output. 1 Then you would create a thread like this:
int main() { int value = 15; pthread_t thread;
If you need to call the Fibonacci function from new separate threads (note: this is not what I would recommend, but others seem to agree with me, it just explodes for a sufficiently large number of iterations), you first need to combine the fibonacci function with fibonacci_offshored functions. This will greatly expand it, because dealing with threads is harder than working with regular functions.
void* threaded_fibonacci(void* pointer) { int* pointer_to_number = pointer; int input = *pointer_to_number; if (input == 0 || input == 1) { *pointer_to_number = 1; return NULL; } // we need one argument per thread int minus_one_number = input - 1; int minus_two_number = input - 2; pthread_t minus_one; pthread_t minus_two; // don't forget to check! especially that in a recursive function where the // recursion set actually grows instead of shrinking, you're bound to fail // at some point if (pthread_create(&minus_one, NULL, threaded_fibonacci, &minus_one_number) != 0) { perror("pthread_create"); *pointer_to_number = 0; return NULL; } if (pthread_create(&minus_two, NULL, threaded_fibonacci, &minus_two_number) != 0) { perror("pthread_create"); *pointer_to_number = 0; return NULL; } if (pthread_join(minus_one, NULL) != 0) { perror("pthread_join"); *pointer_to_number = 0; return NULL; } if (pthread_join(minus_two, NULL) != 0) { perror("pthread_join"); *pointer_to_number = 0; return NULL; } *pointer_to_number = minus_one_number + minus_two_number; return NULL; }
Now that you have this cumbersome function, setting up your main function will be pretty simple: just change the link to fibonacci_offshored to threaded_fibonacci .
int main() { int value = 15; pthread_t thread; int result = pthread_create(&thread, NULL, threaded_fibonacci, &value); if (result != 0) { perror("pthread_create"); return 1; } pthread_join(thread, NULL); printf("The value is %d\n", value); return 0; }
You may have been told that threads are speeding up parallel processes, but there somewhere is somewhere more expensive to set up a thread than to run its contents. This is a very good example of this situation : the streaming version of the program is much slower than the non-streaming version.
For educational purposes, this program ends with threads on my machine when the number of desired iterations is 18 and takes several seconds. For comparison, using an iterative implementation, we never run out of threads, and we have our answer in milliseconds. It is also much simpler. This would be a great example of how using the best algorithm solves many problems.
Also, out of curiosity, it would be interesting to know if your machine crashes and where / how.
<sub> 1. As a rule, you should try to avoid changing the value of a variable between its value at the input and its value after the function returns. For example, here, as you type, the variable represents the number of iterations we want; the output is the result of the function. These are two very different meanings, and this is not a good practice. I did not want to use dynamic allocations to return a value through the return value of void* .