Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. random numbers - the old bugger ...

random numbers - the old bugger ...

Scheduled Pinned Locked Moved C / C++ / MFC
helpsysadmindebugginglounge
11 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Souldrift

    Hey good people, I am in need of an idea for a problem that has to have been solved a throusand times over. But after implementing some code that should take care of the troublemaker (rand()) - but didn´t - and a lot of research I am at a loss here. I built a server which has to generate some random numbers for each client that connects. So I created a nice singleton wrapper class for the random generator and now it´s seeded (srand(time(NULL))) once at startup and thereafter every call should present me an actual (pseudo-)random number. As you may have guessed, theory didn´t work out. All numbers are very random for every single call from ONE client. As soon as another client connects it gets THE SAME 'random' sequence of numbers. Even though the seed was plantet only once AND they don´t even ask at the same time. Here´s a little code on the number generation, maybe someone has an idea:

    ToolBox* ToolBox::m_pToolbox = NULL;

    ToolBox::ToolBox(void)
    {
    m_pLogger = Logger::GetInstance();
    srand ( time(NULL) );
    }

    ToolBox::~ToolBox(void)
    {
    }

    ToolBox* ToolBox::GetInstance()
    {
    if( m_pToolbox == NULL )
    {
    m_pToolbox = new ToolBox();
    }
    return m_pToolbox;
    }

    ///////////////////////////////////////////////////////////////////////////////////
    // Random number generation
    ///////////////////////////////////////////////////////////////////////////////////

    //
    BYTE ToolBox::GenerateRandomByte()
    {
    BYTE ret = LOBYTE((WORD)rand());

        // test random numbers
    int r1 = rand();
    int r2 = rand();
    int r3 = rand();
    int r4 = rand();
    m\_pLogger->Out( Logger::DEBUG, "TestRand 1: %d\\nTestRand 2: %d\\nTestRand 3: %d\\nTestRand 4: %d\\n", r1, r2, r3, r4 );
    
    return ret;	
    

    }

    int ToolBox::GenerateRandomInt()
    {
    return rand();
    }

    Any help is appreciated. Thanks. Souldrift

    M Offline
    M Offline
    Michael Schubert
    wrote on last edited by
    #2

    Have you tried a third party generator? Try this one: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html[^]

    S 1 Reply Last reply
    0
    • S Souldrift

      Hey good people, I am in need of an idea for a problem that has to have been solved a throusand times over. But after implementing some code that should take care of the troublemaker (rand()) - but didn´t - and a lot of research I am at a loss here. I built a server which has to generate some random numbers for each client that connects. So I created a nice singleton wrapper class for the random generator and now it´s seeded (srand(time(NULL))) once at startup and thereafter every call should present me an actual (pseudo-)random number. As you may have guessed, theory didn´t work out. All numbers are very random for every single call from ONE client. As soon as another client connects it gets THE SAME 'random' sequence of numbers. Even though the seed was plantet only once AND they don´t even ask at the same time. Here´s a little code on the number generation, maybe someone has an idea:

      ToolBox* ToolBox::m_pToolbox = NULL;

      ToolBox::ToolBox(void)
      {
      m_pLogger = Logger::GetInstance();
      srand ( time(NULL) );
      }

      ToolBox::~ToolBox(void)
      {
      }

      ToolBox* ToolBox::GetInstance()
      {
      if( m_pToolbox == NULL )
      {
      m_pToolbox = new ToolBox();
      }
      return m_pToolbox;
      }

      ///////////////////////////////////////////////////////////////////////////////////
      // Random number generation
      ///////////////////////////////////////////////////////////////////////////////////

      //
      BYTE ToolBox::GenerateRandomByte()
      {
      BYTE ret = LOBYTE((WORD)rand());

          // test random numbers
      int r1 = rand();
      int r2 = rand();
      int r3 = rand();
      int r4 = rand();
      m\_pLogger->Out( Logger::DEBUG, "TestRand 1: %d\\nTestRand 2: %d\\nTestRand 3: %d\\nTestRand 4: %d\\n", r1, r2, r3, r4 );
      
      return ret;	
      

      }

      int ToolBox::GenerateRandomInt()
      {
      return rand();
      }

      Any help is appreciated. Thanks. Souldrift

      C Offline
      C Offline
      CPallini
      wrote on last edited by
      #3

      You should move the srand call:

      ToolBox::ToolBox(void)
      {
      m_pLogger = Logger::GetInstance();
      srand ( time(NULL) );
      }

      and

      ToolBox* ToolBox::GetInstance()
      {
      if( m_pToolbox == NULL )
      {
      m_pToolbox = new ToolBox();
      srand ( time(NULL) );
      }
      return m_pToolbox;
      }

      [added] Nevermind I made a blunder. [/added] :)

      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
      This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
      [My articles]

      modified on Wednesday, June 24, 2009 8:49 AM

      S 1 Reply Last reply
      0
      • C CPallini

        You should move the srand call:

        ToolBox::ToolBox(void)
        {
        m_pLogger = Logger::GetInstance();
        srand ( time(NULL) );
        }

        and

        ToolBox* ToolBox::GetInstance()
        {
        if( m_pToolbox == NULL )
        {
        m_pToolbox = new ToolBox();
        srand ( time(NULL) );
        }
        return m_pToolbox;
        }

        [added] Nevermind I made a blunder. [/added] :)

        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
        [My articles]

        modified on Wednesday, June 24, 2009 8:49 AM

        S Offline
        S Offline
        Souldrift
        wrote on last edited by
        #4

        umm, where´s the difference. It gets called once either way. Cheers

        C 1 Reply Last reply
        0
        • M Michael Schubert

          Have you tried a third party generator? Try this one: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html[^]

          S Offline
          S Offline
          Souldrift
          wrote on last edited by
          #5

          I´ll look into it, thanks :).

          1 Reply Last reply
          0
          • S Souldrift

            umm, where´s the difference. It gets called once either way. Cheers

            C Offline
            C Offline
            CPallini
            wrote on last edited by
            #6

            Yes, you're right. I made a blunder, forget it. Could you please show us how a client uses the ToolBox? :)

            If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
            This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
            [My articles]

            S 1 Reply Last reply
            0
            • S Souldrift

              Hey good people, I am in need of an idea for a problem that has to have been solved a throusand times over. But after implementing some code that should take care of the troublemaker (rand()) - but didn´t - and a lot of research I am at a loss here. I built a server which has to generate some random numbers for each client that connects. So I created a nice singleton wrapper class for the random generator and now it´s seeded (srand(time(NULL))) once at startup and thereafter every call should present me an actual (pseudo-)random number. As you may have guessed, theory didn´t work out. All numbers are very random for every single call from ONE client. As soon as another client connects it gets THE SAME 'random' sequence of numbers. Even though the seed was plantet only once AND they don´t even ask at the same time. Here´s a little code on the number generation, maybe someone has an idea:

              ToolBox* ToolBox::m_pToolbox = NULL;

              ToolBox::ToolBox(void)
              {
              m_pLogger = Logger::GetInstance();
              srand ( time(NULL) );
              }

              ToolBox::~ToolBox(void)
              {
              }

              ToolBox* ToolBox::GetInstance()
              {
              if( m_pToolbox == NULL )
              {
              m_pToolbox = new ToolBox();
              }
              return m_pToolbox;
              }

              ///////////////////////////////////////////////////////////////////////////////////
              // Random number generation
              ///////////////////////////////////////////////////////////////////////////////////

              //
              BYTE ToolBox::GenerateRandomByte()
              {
              BYTE ret = LOBYTE((WORD)rand());

                  // test random numbers
              int r1 = rand();
              int r2 = rand();
              int r3 = rand();
              int r4 = rand();
              m\_pLogger->Out( Logger::DEBUG, "TestRand 1: %d\\nTestRand 2: %d\\nTestRand 3: %d\\nTestRand 4: %d\\n", r1, r2, r3, r4 );
              
              return ret;	
              

              }

              int ToolBox::GenerateRandomInt()
              {
              return rand();
              }

              Any help is appreciated. Thanks. Souldrift

              S Offline
              S Offline
              Stuart Dootson
              wrote on last edited by
              #7

              Is your application multi-threaded? Because the state of the random number generator is held in per-thread storage (i.e. there's a different random number state for each thread). And if each of those states is initialised the same way...

              Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

              S 1 Reply Last reply
              0
              • C CPallini

                Yes, you're right. I made a blunder, forget it. Could you please show us how a client uses the ToolBox? :)

                If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                [My articles]

                S Offline
                S Offline
                Souldrift
                wrote on last edited by
                #8

                Of course. Only the client doesn´t use the ToolBox. The server does. For each client it has to create an RTP Header for an RTP data transfer. Which is done in my class RTPHeader.

                RTPHeader::RTPHeader( int payloadType )
                {
                m_pLogger = Logger::GetInstance();
                m_pToolbox = ToolBox::GetInstance();
                // setup header
                m_pLogger->Out(Logger::DEBUG, "RTPHeader: Constructing Header.\n");
                for( int i = 0; i < 12; i++ )
                {
                m_aHeader[i] = 0;
                }

                SetPayloadType( payloadType );
                SetVersion( (BYTE) 2 );
                GenerateNewSsrc();
                
                m\_bFirstGetInc = true;
                
                PrintToConsole();
                

                }

                RTPHeader::~RTPHeader(void)
                {
                }

                void RTPHeader::GenerateNewSsrc()
                {
                // does this work properly ??
                m_aHeader[9] = m_pToolbox->GenerateRandomByte();
                m_aHeader[10] = m_pToolbox->GenerateRandomByte();
                m_aHeader[11] = m_pToolbox->GenerateRandomByte();

                }

                .
                .
                .

                In GenerateNewSsrc() the ToolBox´s Random Generator is used. It works nicely for this small piece of code. Only that for the next client that connects to the server it will generate the same sequence all over. And my test output in the ToolBox class actually shows that it is indeed the rand() method that produces the same results. It´s not a variable that wasn´t cleared or such something. A new RTPHeader class object is created for every client. Cheers

                1 Reply Last reply
                0
                • S Stuart Dootson

                  Is your application multi-threaded? Because the state of the random number generator is held in per-thread storage (i.e. there's a different random number state for each thread). And if each of those states is initialised the same way...

                  Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                  S Offline
                  S Offline
                  Souldrift
                  wrote on last edited by
                  #9

                  Hmm .. good idea. That might be it. Though I don´t thoroughly understand it. I indeed use multi-threading. Though there is only one object of the number generator and only one call of srand(). So each thread uses the same instance of the generator, which is actually what I intended because if srand() would be called for each worker thread (one per client), it could happen that two clients connect at the same time, get the same srand()-initialization and therewith produce the same sequence of numbers again. Right? Souldrift

                  S 1 Reply Last reply
                  0
                  • S Souldrift

                    Hmm .. good idea. That might be it. Though I don´t thoroughly understand it. I indeed use multi-threading. Though there is only one object of the number generator and only one call of srand(). So each thread uses the same instance of the generator, which is actually what I intended because if srand() would be called for each worker thread (one per client), it could happen that two clients connect at the same time, get the same srand()-initialization and therewith produce the same sequence of numbers again. Right? Souldrift

                    S Offline
                    S Offline
                    Stuart Dootson
                    wrote on last edited by
                    #10

                    Souldrift wrote:

                    Though there is only one object of the number generator and only one call of srand(). So each thread uses the same instance of the generator, which is actually what I intended because if srand()

                    No, no, no - each thread will have its own random number generator state - it's held inside the C run-time library (look at rand.c in the C run-time source). Even though you have one toolbox object, that's immaterial, because your object doesn't hold the random number state. The call to srand() will only effect the thread on which the toolbox object is constructed. The other threads will get some default random number generator state initialisation. Your best bet would be to use a different PRNG - for example, one of the implementations included in Boost[^], where (as you have full control over the PRNG including the data it uses) you could ensure that you have a single state for ALL threads. Of course, you'd then need to put a lock on the random number acquisition function (to ensure only one thread calls it at once)...

                    Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                    S 1 Reply Last reply
                    0
                    • S Stuart Dootson

                      Souldrift wrote:

                      Though there is only one object of the number generator and only one call of srand(). So each thread uses the same instance of the generator, which is actually what I intended because if srand()

                      No, no, no - each thread will have its own random number generator state - it's held inside the C run-time library (look at rand.c in the C run-time source). Even though you have one toolbox object, that's immaterial, because your object doesn't hold the random number state. The call to srand() will only effect the thread on which the toolbox object is constructed. The other threads will get some default random number generator state initialisation. Your best bet would be to use a different PRNG - for example, one of the implementations included in Boost[^], where (as you have full control over the PRNG including the data it uses) you could ensure that you have a single state for ALL threads. Of course, you'd then need to put a lock on the random number acquisition function (to ensure only one thread calls it at once)...

                      Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                      S Offline
                      S Offline
                      Souldrift
                      wrote on last edited by
                      #11

                      Okay. That´s good to know :). I´ll look into Boost. And sure thing about the lock ... I would have taken care of that later on, anyway. Thanks for now Souldrift

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups