Last active
June 19, 2024 20:28
-
-
Save pedrominicz/785149528955a6be9894a64ad35300cc to your computer and use it in GitHub Desktop.
Multithreaded Fibonacci using POSIX threads.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pthread.h> | |
#include <stdarg.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
// This program illustrates the use of POSIX threads. | |
// | |
// A POSIX thread has two main components: an object of type `pthread_t` which | |
// represents the thread and a function pointer of type `void* (*)(void*)` | |
// which will be the entry point of the thread. | |
// This function is taken from `http://git.suckless.org/dwm/file/util.c.html`. | |
// | |
// Print the error message and `perror` if the message ends in `':'`. Assumes | |
// `fmt` is not `NULL`. | |
void die(const char* fmt, ...) { | |
va_list ap; | |
va_start(ap, fmt); | |
vfprintf(stderr, fmt, ap); | |
va_end(ap); | |
// Following Unix convention (see `man perror`), first check if the string is | |
// not empty. | |
if(fmt[0] && fmt[strlen(fmt) - 1] == ':') { | |
fputc(' ', stderr); | |
perror(NULL); | |
} else { | |
fputc('\n', stderr); | |
} | |
exit(0); | |
} | |
void* fib(void* arg) { | |
int n = *(int*)arg; | |
if(n < 2) { | |
int* ret = malloc(sizeof(int)); | |
*ret = 1; | |
return ret; | |
} | |
// Allocate `n - 1` and `n - 2` on the stack. Necessary because we give | |
// addresses of these values to the threads. | |
int n1 = n - 1; | |
int n2 = n - 2; | |
pthread_t t1, t2; | |
// Creates new threads. The second argument is a pointer to a | |
// `pthread_attr_t`, if `NULL` the thread is created with default attributes. | |
if(pthread_create(&t1, NULL, fib, &n1)) die("unable to create thread"); | |
if(pthread_create(&t2, NULL, fib, &n2)) die("unable to create thread"); | |
int* ret1; | |
int* ret2; | |
// Wait for the threads to terminate. The return value of the thread is | |
// copied into the value pointed by the second argument. | |
if(pthread_join(t1, (void**)&ret1)) die("unable to join thread"); | |
if(pthread_join(t2, (void**)&ret2)) die("unable to join thread"); | |
int* ret = malloc(sizeof(int)); | |
*ret = *ret1 + *ret2; | |
free(ret1); | |
free(ret2); | |
return ret; | |
} | |
int main(int argc, char** argv) { | |
for(int i = 0; i < 10; ++i) { | |
int* ret = fib(&i); | |
printf("%d\n", *ret); | |
free(ret); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment