2

I have a source file in which I defined a function to fill a vector with random 1 or 0, something like:

int rand_range(int lo, int hi) {
 return lo + rand_r(&seed) % (hi - lo);
}
//fill a vector with n 1 and N-n 0 at random
void random_fill(int vec[], int dim, int n) {
 int i;
 //the condition is n!=0!
 for (i = 0; n; ++i) {
  if (rand_range(0, dim-i) < n) {
   vec[i] = 1;
   --n;
 }
 else
   vec[i] = 0;
 }
 for (; i < dim; ++i) vec[i] = 0;
}

seed is a variable declared in the same source file.

In my main.c file I use openmp() to parallelize my program, but I have to call this function in every thread. If I simply call:

random_fill(vec, dim, n);

inside the parallelized area, do I get issues? What's the most correct way to call a function that generates and works with random numbers in a thread safe way?


I think this question is somehow different from this one, because in this case My threads don't seed anything, but they use a function defined in a source file. So I don't understand if there's a way to make this operation thread safe. In other words, how do I call functions that generate random numbers inside a parallelized area?

Community
  • 1
  • 1
  • See this doc: http://stackoverflow.com/questions/3973665/how-do-i-use-rand-r-and-how-do-i-use-it-in-a-thread-safe-way – TheGuyWhoForgetsALot Jan 30 '17 at 21:53
  • Yeah I saw that post but I fail to understand if I have to change something in my code... – Francesco Di Lauro Jan 30 '17 at 21:55
  • Possible duplicate of [How do I use rand\_r and how do I use it in a thread safe way?](http://stackoverflow.com/questions/3973665/how-do-i-use-rand-r-and-how-do-i-use-it-in-a-thread-safe-way) – TheGuyWhoForgetsALot Jan 30 '17 at 21:56
  • If you access a `static` object from multiple threads in a non-readonly, non-atomic, unsynchronized way, you have a data-race and undefined behavior. You *could* use a `_Thread_local` instead, but you're better off passing a pointer to an allocated or automatic per-thread object instead. – EOF Jan 30 '17 at 22:03
  • So I should modify my function random_fill to accept a pointer which will be my seed for the call, so I can choose different seeds for different threads? – Francesco Di Lauro Jan 30 '17 at 22:06
  • Note that POSIX marks [`rand_r()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/rand_r.html) as an obsolescent C extension that may be removed in a future edition. You should look at the [`drand48()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html) or [`random()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/random.html) functions instead. – Jonathan Leffler Jan 30 '17 at 22:14
  • @FrancescoDiLauro I believe you would have to make sure `rand_range()` and `random_fill()` are both re-entrant to make them thread-safe. – Chimera Jan 30 '17 at 22:16
  • 1
    You have to review carefully your requirements on the random numbers, and decide whether each thread has its own sequence (and hence its own seed), or whether they all share a single sequence and hence share a seed, with requirements to enforce mutual exclusion on the calls to `rand_r()` with that shared seed. One issue to consider will be repeatability — with multiple threads sharing a single seed, it will be hard to get reproducibility of the random sequences, which may make testing into a painful process. If each thread has its own sequence, each thread is more nearly repeatable. – Jonathan Leffler Jan 30 '17 at 22:18
  • @Chimera How, in principle, should I make sure that these functions are re-entrant? I would like to get reproducibility so I rather give every a thread a seed. What I don't understand is how to make my fucntion thread safe without using that seed thing – Francesco Di Lauro Jan 30 '17 at 22:35
  • @FrancescoDiLauro Sorry. Forget about the re-entrance issue. That only matters, generally, in a single threaded application. https://en.wikipedia.org/wiki/Reentrancy_(computing). – Chimera Jan 31 '17 at 16:26

0 Answers0