random numbers - the old bugger ...
-
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
Have you tried a third party generator? Try this one: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html[^]
-
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
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
-
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
-
Have you tried a third party generator? Try this one: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html[^]
-
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] -
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
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
-
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]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
-
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
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
-
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
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
-
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