Last active
July 12, 2019 14:11
-
-
Save carc1n0gen/1c3fe2fa5f1312993e1d to your computer and use it in GitHub Desktop.
Thread safe random numbers in c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <time.h> | |
#include <threads.h> | |
//#define NUM_THREADS 7 | |
// Thread safe random numbers by tempering the upper 32 bits | |
// of a 64 bit int. The calculations are based on a seed. | |
// | |
// Create a single seed per thread and use that for every call | |
// lcg64_temper. | |
// | |
// credit: http://stackoverflow.com/a/19083740/2635342 | |
static int32_t temper(int32_t x) | |
{ | |
x ^= x>>11; | |
x ^= x<<7 & 0x9D2C5680; | |
x ^= x<<15 & 0xEFC60000; | |
x ^= x>>18; | |
return x; | |
} | |
int32_t lcg64_temper(uint64_t *seed) | |
{ | |
*seed = 6364136223846793005ULL * *seed + 1; | |
return temper(*seed >> 32); | |
} | |
int threadFunction(void* data) | |
{ | |
int32_t id = *(int32_t*)data; | |
printf("%d-th thread up\n", id); | |
uint64_t threadSeed = time(NULL) ^ id; | |
int32_t n = lcg64_temper(&threadSeed) % 20 + 1; | |
thrd_sleep(&(struct timespec){ .tv_sec = n }, NULL); // Sleep for a random number of seconds. | |
printf("%d-th thread done\n", id); | |
return 0; | |
} | |
int main(void) | |
{ | |
const size_t NUM_THREADS = 7; | |
int32_t threadData[NUM_THREADS]; | |
thrd_t threads[NUM_THREADS]; | |
// Initialize data for each thread. | |
for (size_t i = 0; i < NUM_THREADS; ++i) | |
{ | |
threadData[i] = i; | |
} | |
// Create the threads. | |
for (size_t i = 0; i < NUM_THREADS; ++i) | |
{ | |
if (thrd_create(threads+i, threadFunction, threadData+i) != thrd_success) | |
{ | |
printf("%zu-th thread create error\n", i); | |
return 1; | |
} | |
} | |
// Wait for all threads to complete. | |
for (size_t i = 0; i < NUM_THREADS; ++i) | |
thrd_join(threads[i], NULL); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment