Skip to content

Instantly share code, notes, and snippets.

@alanxoc3
Created February 26, 2018 04:46
Show Gist options
  • Save alanxoc3/cbc27f319116af176f19b96ded89fcde to your computer and use it in GitHub Desktop.
Save alanxoc3/cbc27f319116af176f19b96ded89fcde to your computer and use it in GitHub Desktop.
Almost Thread Safe C Increment example.
// Thread demo by Alan Morgan.
// Empirically, this example seems thread safe.
// But, it may be possible for 2 children to exit the while loop at the same time.
// Thus I must ask the question. Is true thread safety even possible!!!
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
void* create_shared_memory(size_t size) {
// Our memory buffer will be readable and writable:
int protection = PROT_READ | PROT_WRITE;
// The buffer will be shared (meaning other processes can access it), but
// anonymous (meaning third-party processes cannot obtain an address for it),
// so only this process and its children will be able to use it:
int visibility = MAP_ANONYMOUS | MAP_SHARED;
// The remaining parameters to `mmap()` are not important for this use case,
// but the manpage for `mmap` explains their purpose.
return mmap(NULL, size, protection, visibility, 0, 0);
}
struct thready {
int num;
char safe;
};
int main() {
while(1) {
struct thready init_val = {0, 0};
struct thready* thready = create_shared_memory(sizeof(struct thready));
memset(thready, 0, sizeof(char));
for (int i = 0; i < 100; ++i) {
// if a child process
if (!fork()) {
while(thready->safe != 0);
thready->safe = 1;
thready->num += 1;
thready->safe = 0;
exit(0);
}
}
while(wait(NULL) > 0);
printf("Final val is: %d\n", thready->num);
if (thready->num != 100) {
break;
}
munmap(thready, sizeof(struct thready));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment