Skip to content

Instantly share code, notes, and snippets.

@pedrominicz
Last active March 15, 2020 14:20
Show Gist options
  • Save pedrominicz/382039ec888e7b4ba399f55b0475ef75 to your computer and use it in GitHub Desktop.
Save pedrominicz/382039ec888e7b4ba399f55b0475ef75 to your computer and use it in GitHub Desktop.
Strict alternation in C.
#include <pthread.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// This program illustrates the use of strict alternation to synchronize
// threads. Two new threads are created and alternate writing to the standard
// output.
// 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);
}
// This variable is accessible from both threads. Each thread only execute
// their critical section when its their turn and signal to eachother that
// their turn is over by modifying the flag.
int turn = 0;
void* f0(void* arg) {
while(1) {
// Wait until its this thread's turn.
while(turn != 0);
puts("hello");
// Signal to the other thread that its their turn.
turn = 1;
sleep(1);
}
}
void* f1(void* arg) {
while(1) {
while(turn != 1);
puts("world");
turn = 0;
sleep(1);
}
}
int main(void) {
// 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.
pthread_t t0, t1;
// Creates new threads. The second argument is a pointer to a
// `pthread_attr_t`, if `NULL` the thread is created with default attributes.
// The last argument is the argument that is given to the thread's entry
// point function, unused in this example.
if(pthread_create(&t0, NULL, f0, NULL)) die("unable to create thread");
if(pthread_create(&t1, NULL, f1, NULL)) die("unable to create thread");
// Yes, I could have just created one extra thread.
while(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment