Skip to content

Instantly share code, notes, and snippets.

@pedrominicz
Last active June 19, 2024 20:28
Show Gist options
  • Save pedrominicz/785149528955a6be9894a64ad35300cc to your computer and use it in GitHub Desktop.
Save pedrominicz/785149528955a6be9894a64ad35300cc to your computer and use it in GitHub Desktop.
Multithreaded Fibonacci using POSIX threads.
#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