Skip to content

Instantly share code, notes, and snippets.

@Cartroo
Last active June 6, 2025 08:55
Show Gist options
  • Save Cartroo/11881ef4364bfb459402f527184c5022 to your computer and use it in GitHub Desktop.
Save Cartroo/11881ef4364bfb459402f527184c5022 to your computer and use it in GitHub Desktop.
Simple demonstration of a shared counter protected by a shared pthread mutex between multiple processes.
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <unistd.h>
struct shared_data
{
unsigned int counter;
pthread_mutex_t mutex;
};
void child_loop(struct shared_data *shared)
{
for (int i = 0; i < 100; ++i) {
pthread_mutex_lock(&shared->mutex);
unsigned int old_counter_value = shared->counter;
// Sleep up to 100ms
usleep(rand() % (100 * 1000));
shared->counter = old_counter_value + 1;
pthread_mutex_unlock(&shared->mutex);
}
}
int main()
{
// Create shared data section using anonymous mmap.
struct shared_data *shared = (struct shared_data*)mmap(
NULL,
sizeof(struct shared_data),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS,
-1,
0);
if (shared == MAP_FAILED) {
printf("mmap failed\n");
return 1;
}
// Initialise the shared data, and its mutex.
shared->counter = 0;
pthread_mutexattr_t mutexattr;
if (pthread_mutexattr_init(&mutexattr) != 0) {
printf("pthread_mutexattr_init failed\n");
return 1;
}
if (pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) != 0) {
printf("pthread_mutexattr_setpshared failed\n");
return 1;
}
if (pthread_mutex_init(&shared->mutex, &mutexattr) != 0) {
printf("pthread_mutex_init failed\n");
return 1;
}
// Create five child processes using the shared data.
for (int i = 0; i < 5; ++i) {
pid_t ret = fork();
if (ret < 0) {
printf("fork failed\n");
} else if (ret == 0) {
printf("running child...\n");
child_loop(shared);
printf("child done\n");
// Important to terminate here, not exit the loop in children.
return 0;
} else {
printf("created child %d\n", ret);
}
}
// Wait until there are no more children.
printf("parent waiting for children...\n");
while (1) {
pid_t ret = wait(0);
if (ret < 0) {
if (errno != ECHILD) {
printf("unexpected error from wait: %s\n", strerror(errno));
}
break;
}
printf("child %d terminated\n", ret);
}
// Finally, print the final counter result.
printf("final value of counter: %d\n", shared->counter);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment