Как-то я потратил довольно много времени, пытаясь понять, почему десяток асинхронных запросов к PHP-скрипту выстраивается в очередь вместо того, чтобы отрабатывать параллельно.
Чтобы показать наглядно, набросаем пару тестовых скриптов.
test1.php
<?php
session_start();
sleep(10);
echo '1';
test2.php
<?php
session_start();
echo '2';
Ничего необычного, правда?
Теперь запустим их параллельно. Воспользуемся jQuery:
$.get('/test1.php');
$.get('/test2.php');
В итоге получается вот такая картинка (это вкладка Net из Firebug):

test1.php
заблокировал работу test2.php
.
При использовании сессий «из коробки», данные хранятся в одном единственном файле, который оказывается заблокированным с момента вызова session_start
и до окончания работы скрипта.
В том случае, если сессия вам нужна только для чтения, или есть возможность записать всё необходимое перед медленной частью скрипта, можно её закрыть явно при помощи session_write_close()
:
<?php
session_start();
session_write_close();
sleep(10);
echo '1';
В этом случае мы получим желаемую картину:

Если же необходимо писать в сессию после медленных операций, придётся сменить «коробочную» сессию на свою реализацию с неблокируемым хранилищем, таким, например, как база данных.
Стоит отметить, что если при этом не позаботится о race condition, можно наступить на хорошие такие грабли.
Материалы: