Gordon McKeown wrote:
Apologies, my mail client was supposed to line-wrap that for me....

-----

Hi,

I'm currently experiencing a problem with a phpBB board that appears
to be due to the way random number generation works in PHP. I have
posted on serveral phpBB boards and have received no answers, so I
think I need to understand how PHP is dealing with this in order to
resolve it.

phpBB generates a unique index for search results using the following
code (in search.php):

----- 8< ----- Code ----- 8< -----
mt_srand ((double) microtime() * 1000000); $search_id = mt_rand();
----- 8< ----- Code ----- 8< -----

The problem is that the seed is generated from the system clock, and
if two people search at the exact same moment (or more strictly, if
the mt_srand statements get executed at the exact same moment), the
random number generation system is initialised with the same seed in
each case, so both searches receive the same $search_id, resulting in
a MySQL error due to non-unique index fields.

Looking through the documentation for PHP, it seems that versions >
4.2.0 do not require the use of mt_srand as they will seed themselves
when required. I've had a look at the PHP source code, and from my
limited understanding, the seed appears to be generated using a
function in php_rand.h:

----- 8< ----- Code ----- 8< -----
#define GENERATE_SEED() ((long)(time(0) * getpid() * 1000000 \
* php_combined_lcg(TSRMLS_C)))
----- 8< ----- Code ----- 8< -----

no need to look as far inside as that... :)
So this is still based to some extent on the current system clock,
and the php_combined_lcg function in lcg.c also appears to rely on
the current system clock along with the current process/thread ID.

There is also some code to ensure that seeding only occurs once. But
is this once per thread? Once per process? Once per something-else?
per process

What I'm trying to find out is whether this new seeding system will produce the same 'random' number if two mt_rand() statements are executing concurrently. My guess is that they won't, but I don't understand the internals of PHP or Apache well enough to know if their use of threads and processes will ensure uniqueness.
Comment out the seeding if you're using PHP 4.2.0+ and it'll work fine. (mt_srand function, not the mt_rand one!)

The problem is occuring with PHP 4.3.9 running under Apache 1.3.33 on
Linux kernel 2.4.26 (on a fairly typical cPanel-based shared hosting
box). Unfortunately due to the timing-based nature of the problem,
it has proven very difficult to set up test cases.

I'd be very grateful for any assistance.

Gordon.

-- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php



Reply via email to