Is mersenne twister thread safe for cpp

前端 未结 2 1773
[愿得一人]
[愿得一人] 2021-01-18 08:59
#include 

int f() {

    std::random_device seeder;
    std::mt19937 engine(seeder());
    std::uniform_int_distribution dist(1, 6);

    r         


        
2条回答
  •  后悔当初
    2021-01-18 09:16

    No C++ std type uses global data in a non-thread-safe way. Two unrelated instances of such a type can be accessed in different threads.

    By default, one instance of a type cannot be accessed from two threads without synchronization.

    You are created local variables. These local variables are unrelated to any other instance of their type. There are no thread safety issues here.

    Pseudo-random values are most efficiently produced by having state and reusing it. You are not doing this, so your random number from 1 to 6 will be relatively expensive to create.

    std::random_device seeder;
    std::mt19937 engine(seeder());
    std::uniform_int_distribution dist(1, 6);
    return dist(engine);
    

    Your use of std::mt19937 is redundant. You are already creating a random_device, which could be fed to dist directly, and then created an engine from it, then using the engine. The use of engine here is useless.

    Traditionaly you create an engine (of some type, like mt19937) once from a seeder. You then store the engine, and repeatedly pass it to distributions.

    This does the relatively expensive "real random number" generation once to generate a long series of pseudo-random numbers via engine through distribution.

    Note, however, that such use has a cost; you must store the engine and you must prevent multiple-thread access to it.

    The "right" way to do this is to have an object that produces random values for you, and pass it around where you need it. Storing the initial seed used would also permit you to repeat the execution of the set of random numbers involved.

    If you don't like the idea of explicitly passing around your random state, you could use a thread_local (or static with a mutex guard).

    thread_local std::mt19937 engine(std::random_device{}());
    std::uniform_int_distribution dist(1, 6);
    return dist(engine);
    

    This creates one engine per thread, and the engine is initialized with a value from your random_device.

提交回复
热议问题