简体   繁体   中英

How does session_start lock in PHP?

Originally, I just want to verify that session_start locks on session. So, I create a PHP file as below. Basically, if the pageview is even, the page sleeps for 10 seconds; if the pageview is odd, it doesn't. And, session_start is used to obtain the page view in $_SESSION .

I tried to access the page in two tabs of one browser. It is not surprising that the first tab takes 10 seconds since I explicitly let it sleep. The second tab would not sleep, but it should be blocked by sessiont_start . That works as expected.

To my surprise, the output of the second page shows that session_start takes almost no time. Actually, the whole page seems takes no time to load. But, the page does take 10 seconds to show in browser.

obtained lock
Cost time: 0.00016689300537109
Start 1269739162.1997
End 1269739162.1998
allover time elpased : 0.00032305717468262
The page views: 101

Does PHP extract session_start out of PHP page and execute it before other PHP statements?

This is the code.

<?php

function float_time()
{
    list($usec, $sec) = explode(' ', microtime());
    return (float)$sec + (float)$usec;
}

$allover_start_time = float_time();

$start_time = float_time();

session_start();

echo "obtained lock<br/>";
$end_time = float_time();

$elapsed_time = $end_time - $start_time;
echo "Cost time: $elapsed_time <br>";
echo "Start $start_time<br/>";
echo "End $end_time<br/>";
ob_flush();
flush();


if (isset($_SESSION['views']))
{
    $_SESSION['views'] += 1;
}
else
{
    $_SESSION['views'] = 0;
}

if ($_SESSION['views'] % 2 == 0)
{
    echo "sleep 10 seconds<br/>";
    sleep(10);
}

$allover_end_time = float_time();
echo "allover time elpased : " . ($allover_end_time - $allover_start_time) . "<br/>";

echo "The page views: " . $_SESSION['views'];

?>

That seems to be a firefox related "issue". If you request the same url in two tabs/windows the second request waits until the first request is finished (could also be an addon that blocks the second request, haven't tested that).
Take eg

<?php // test.php
$start = microtime(true);
echo "<pre>start: $start</pre>";
sleep(5);
$end = microtime(true);

echo '<pre>', $start, "\n", $end, "\n", $end-$start, '</pre>';

I called it twice and the output was

start: 1269742677.6094

1269742677.6094
1269742682.609
4.9995958805084

and

start: 1269742682.6563

1269742682.6563
1269742687.6557
4.9994258880615

Note that there's already a 5 second gap between the start times.

When called as http://localhost/test.php and http://localhost/test.php?a=b instead of the exact same url twice this does not happen.
Both IE8 and Chrome do not show that behavior.

Yes, This could be because of session_start() blocking other requests in the same session (file based). I was able to verify the issue in Firefox(4.x) and Chrome(10.x) in Windows XP/PHP 5.2 with default session handler(file). I am not sure if this issue is reproducible for non-file session handlers.

obtained lock
**Cost time: 9.90100598335**
Start 1303227658.67
End 1303227668.57
sleep 10 seconds
allover time elpased : 19.9027831554
The page views: 4

This is a very interesting issue and the Firefox tab locking described in the above answer would have eclipsed this one from being detected.

http://www.php.net/manual/en/function.session-start.php#101452

Since php does not have a container. How do two calls to same session get serialized? Who does this? How do the two processes talk? Is PHP module always active and only spawning threads after doing session check? In that case the PHP module is indeed behaving like a container that is, in this case, providing session management service to this extent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM