G_Man
G_Man

Reputation: 169

Threads, how to seed random number generator independently?

I asked a question here yesterday about threads and getting input to create the amount of threads the user specifies. I was able to figure it out with you guy's help. I am working on the same program except this time, I need help with getting each thread in my program to independently seed the random number generator. M apologies if this sounds simple. I'm still new to threads.

Basically what my program is doing is asking the user how many threads they want to create, and how many arrows they want to throw. Each arrow will generate 2 numbers each, from -1 to 1. This is my program so far. It's working code so you can just run it if you need to:

#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
#include <thread>

using namespace std;

void exec(int n, int randNumbers)
{
    int seed = 0;

    srand(seed);
    int random_number = rand() % 1 + -1;

    cout << "Thread " << n << endl;
    cout << "\n";

    while (randNumbers != 0)
    {
        srand(seed);
        cout << random_number << endl;
        seed++;
        cout << "Seed: " << seed << endl;
        cout << "\n";

        cout << random_number << endl;
        seed++;
        cout << "Seed: " << seed << endl;
        cout << "\n";
        randNumbers--;
    }
}


int main()
{
    int numThreads = 0; // Threads
    int maxRandom; // Arrows

    cout << "This is a Monte Carlo simulation." << endl;
    cout << "Please enter the number of threads to run." << endl;
    cout << "Threads: ";

    cin >> numThreads;

    // create an array of threads
    thread* myThreads = new thread[numThreads];

    if ((numThreads > 20) || (numThreads < 1))
    {
        cout << "Sorry. Something went wrong." << endl;
        return 0;
    }

    system("CLS");
    cout << "\n";
    cout << "Enter the number of arrows you would like to throw: " << endl;
    cout << "Arrows: ";

    cin >> maxRandom; // Arrows

    system("CLS");
    for (int i = 0; i < numThreads; i++)
    {
        // run random number generator for thread at [i]
        myThreads[i] = thread(exec, i, maxRandom);
    }

    for (int i = 0; i < numThreads; i++)
    {
        myThreads[i].join();
    }

    cout << "Done!" << endl;
}

All threads are returning -1 regardless of if int seed goes up by 1. I've looked all over but I still can't seem to figure out why my threads aren't independently seeding the random number generator. Anyone know what is going on? I'm still new to threads. Any bit of help would be greatly appreciated. Thank you very much.

Upvotes: 3

Views: 1572

Answers (1)

Daniel Langr
Daniel Langr

Reputation: 23497

  1. Be sure that each thread has its own private PRNG (using one shared PRNG by all threads would need locking and would be terribly slow due to waiting and cache contention).
  2. Katzgraber has proposed a seeding of PRNGs based on process/thread numbers in Section 7.1 of Random Numbers in Scientific Computing: An Introduction.

It looks like:

long seedgen(void) {
    long s, seed, pid; // pid from 0 to number of processes/threads - 1
    pid = ...; /* get processt/thread ID */
    s = time ( &seconds ); /* get CPU seconds since 01/01/1970 */
    seed = abs(((s * 181) * ((pid - 83) * 359)) % 104729);
    return seed;
}

Upvotes: 2

Related Questions