简体   繁体   中英

What is the benefit of using static thread_local with std::mt19937?

I have seen several usages of std::mt19937 like following:

#include <random>

size_t get_rand()
{
    static thread_local std::mt19937 generator(time(0));
    std::uniform_int_distribution<int> distribution(0, 10);
    return distribution(generator);
}

I want to find out what benefits comes from using static thread_local rather than static here. // first static is redundant

I understand that in the second case generator has lifetime until thread is finished. Are there other benefits/differences in common or this particular case?

If it wasn't thread_local , then calling get_rand from multiple threads would cause a data race and therefore undefined behavior.

Although the static initialization is always safe, even with multiple threads calling it, the call to the generator in distribution(generator) , which modifies the generator's internal state, is not.

With thread_local each thread has its own generator and so there is no issue with them calling the function unsynchronized.


Also note that time(0) is a bad idea. General issue with that as a seed aside, if multiple threads call the function at a similar time, they are likely to be seeded with the same value and then the random numbers in the threads will all be identical (which is very likely not what you want).

A somewhat better seeding would be

thread_local std::mt19937 generator(std::random_device{}());

instead, assuming your platform implements std::random_device as a proper source of randomness (which should generally be the case, but eg is not on some versions of MinGW). (Be careful though if your platform does not properly implement std::random_device . In that case it might always produce the same sequence of numbers.) For more details on seeding the standard library random number generators see eg this question . Also note that even with platform support, this is still a mediocre seeding since it (typically) uses only 32bits of entropy. See eg this blog post for some details about these issues. Correct seeding is a quite non-trivial problem.

For a declaration at block scope static is redundant by the way when using thread_local .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM