'Is this a thread-safe RNG method?
Is it safe to call A::generateID() from multiple threads?
class A
{
public:
std::string generateID()
{
unsigned long rndNumber = dist(gen);
std::string result;
result.resize(5);
result[0] = LETTERS[(rndNumber >> (6*0)) & 0x3f];
result[1] = LETTERS[(rndNumber >> (6*1)) & 0x3f];
result[2] = LETTERS[(rndNumber >> (6*2)) & 0x3f];
result[3] = LETTERS[(rndNumber >> (6*3)) & 0x3f];
result[4] = LETTERS[(rndNumber >> (6*4)) & 0x3f];
return result;
}
private:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937_64 gen = std::mt19937_64(seed); //Has the best performance compared to other RNG engines
std::uniform_int_distribution<unsigned long> dist = std::uniform_int_distribution<unsigned long>(0, std::numeric_limits<unsigned long>::max());
const std::string LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&$";
};
Of course, the easiest way would be just putting everything in generateID() but I want to do as much work as possible in the object instatiation to make the function call as fast as possible and it must be thread-safe. The problem is, dist(gen) seems to change the internal state of the RNG engine but I can't find any information about the race conditions of std::uniform_int_distribution::operator().
Solution 1:[1]
Absolutely not, uniform_int_distribution is not thread safe.
And it's actually much worse, because you're using one uniformly-distributed random value and generate 5 random values from it that are absolutely not uniformly-distributed. If you want 5 random values, request 5 values from your generator. You're not gaining anything with your anti-pattern.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Blindy |
