Skip to content

Instantly share code, notes, and snippets.

@submachine
Last active December 28, 2015 18:48
Show Gist options
  • Save submachine/7545489 to your computer and use it in GitHub Desktop.
Save submachine/7545489 to your computer and use it in GitHub Desktop.
A 'Hello World!' program unnecessarily using libpthread
/*
gcc -O0 -std=c99 -pedantic -Wall -Werror -lpthread \
-o hello-pthread hello-pthread.c
*/
/* Enable 2008 edition functionality of POSIX.1,
required for pthread_rwlock_* functions. */
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
char *sentence[] = { "Hello, ",
"disturbingly ",
"twisted ",
"little ",
"world!\n"
};
#define NWORDS (sizeof (sentence) / sizeof (char *))
/* Number of times we want to print the sentence. */
#ifndef REPEAT
#define REPEAT 1000
#endif
/* How long the main thread makes workers wait for work. */
#if WAIT
#else
#define WAIT 5
#endif
#define copy(d,s) \
do \
{ \
int i; \
for (i = 0; i < NWORDS; i++) \
(d)[i] = (s)[i]; \
} while (0)
pthread_mutex_t m;
pthread_rwlock_t l;
char *words[NWORDS];
int next_word;
/* Each thread copies the words over to a local 'my_words', then prints
the word 'my_words[next_word]' REPEAT times while updating 'next_word'.
We do this REPEAT times so as to cause contention for the mutex. */
void *
thread (void *x)
{
char *my_words[NWORDS];
int i;
pthread_rwlock_rdlock (&l);
copy (my_words, words);
pthread_rwlock_unlock (&l);
for (i = 0; i < 1000; i++)
{
pthread_mutex_lock (&m);
printf ("%s", my_words[next_word++]);
/* If we finished writing the words, we start over again. */
if (next_word == NWORDS)
next_word = 0;
pthread_mutex_unlock (&m);
}
pthread_exit (NULL);
}
int
main (void)
{
int i;
pthread_t threads[NWORDS];
pthread_mutex_init (&m, NULL);
pthread_rwlock_init (&l, NULL);
pthread_mutex_lock (&m);
pthread_rwlock_wrlock (&l);
for (i = 0; i < NWORDS; i++)
pthread_create (threads + i, NULL, thread, NULL);
/* Make the threads wait at rdlock(&l) before they can read 'words'. */
sleep (WAIT);
copy (words, sentence);
pthread_rwlock_unlock (&l);
/* Make the threads wait at lock(&m) before they can use 'next_word'. */
sleep (WAIT);
next_word = 0;
pthread_mutex_unlock (&m);
for (i = 0; i < NWORDS; i++)
pthread_join (threads[i], NULL);
pthread_mutex_destroy (&m);
pthread_rwlock_destroy (&l);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment