sleep(), fsockopen() и пр блокируют выполнение session_init() (парадокс дня)

stillwaiting

Новичок
sleep(), fsockopen() и пр блокируют выполнение session_init() (парадокс дня)

Пребываю в шоке. И вот по какому поводу:

Исходные данные:

http://sapper4ever.net/test/lock.php - инициализирует сессию, спит 20 секунд и пишет время выполнения себя любимого.
PHP:
<?php

    $start = time();
    session_start();
    sleep(20);
    echo "I'm the Locker!, execution time: ".(time() - $start);




// Show file content


    $content = file_get_contents($_SERVER['SCRIPT_FILENAME']);
    echo "<pre>".htmlspecialchars($content)."</pre>";

?>
http://sapper4ever.net/test/simplescript.php - замеряет время инициализации сессии.
PHP:
<?php
    ob_start();

    $start = time();
    echo "Point1 - before session_start() : ".(time() - $start)."<br />";

    session_start();

    echo "Point2 - after session_start() : ".(time() - $start)."<br />";

    ob_end_flush();


// Show file content


    $content = file_get_contents($_SERVER['SCRIPT_FILENAME']);
    echo "<pre>".htmlspecialchars($content)."</pre>";
?>
http://sapper4ever.net/test/info.php
PHP:
<?php
    echo phpinfo();
?>
Эксперимент:

запускаю simplescript.php, он выдает:
Код:
Point1 - before session_start() : 0
Point2 - after session_start() : 0
запускаю lock.php, он выдает:
Код:
I'm the Locker!, execution time: 20
запускаю сначала lock.php, потом паралельно simplescript.php. simplescript.php выдает:
Код:
Point1 - before session_start() : 0
Point2 - after session_start() : 19
Вопросы:
1. Это - нормальное поведение?
2. Какие варианты, чтобы simplescript не дожидался завершения sleep() у lock.php а чтобы они работали паралельно не мешая друг другу? Самый простой: выключать сессии перед sleep(), затем включать обратно.

PS. Такая же фигня происходит если sleep заменить на fsockopen (непроверенная информация).

Очень надеюсь на помощь, поддержку и взаимопонимание.

Спасибо за внимание!

-~{}~ 25.07.08 11:56:

PPS в 5-м php такая же фигня (на хостинге где проходил эксперимент 4-й).
 

Gas

может по одной?
Самый простой: выключать сессии перед sleep(), затем включать обратно.
а так-же самый правильный и наверное единственно возможный. при session_start() лочится файл сессии и другие процессы ждут когда он (lock) будет снят.
 

stillwaiting

Новичок
2Gas Спасибо за ответ. блин! вот же век живи - век учись.

Новые вопросы:
1. А это отражено где-нибудь в доках, хочется почитать, не подскажешь?
2. А если использовать session_set_save_handler() и писать сессии например в БД? Eсли дело в файле который лочится, то это можно сделать более гибко, блокировать запись только на время записи...
3. И это типа разумно? Лочить файл и "пусть весь мир подождет"?
 

SiMM

Новичок
Из FAQ:
Следует помнить, что пхп лочит файл сессии. То есть, если один ваш скрипт стартует сессию и долго выполняется, а другой пытается в это время стартовать её с тем же идентификатором, то он зависнет.

> 2. А если использовать session_set_save_handler() и писать сессии например в БД? Eсли дело в файле который лочится, то это можно сделать более гибко, блокировать запись только на время записи...
Простенький скрипт:
PHP:
session_start();
@$_SESSION['counter']++;
в этом случае не имел бы никакого отношения к количеству запусков скрипта, ибо пропускал бы параллельные вызовы.

> 3. И это типа разумно? Лочить файл и "пусть весь мир подождет"?
А это типа разумно, держать сессию открытой, когда она уже ненужна?
 

stillwaiting

Новичок
Автор оригинала: SiMM
Из FAQ:
Следует помнить, что пхп лочит файл сессии. То есть, если один ваш скрипт стартует сессию и долго выполняется, а другой пытается в это время стартовать её с тем же идентификатором, то он зависнет.
Да, это я осознал, спасибо
> 2. А если использовать session_set_save_handler() и писать сессии например в БД? Eсли дело в файле который лочится, то это можно сделать более гибко, блокировать запись только на время записи...
Простенький скрипт:
PHP:
session_start();
@$_SESSION['counter']++;
в этом случае не имел бы никакого отношения к количеству запусков скрипта, ибо пропускал бы параллельные вызовы.
Не совсем понял, что этот пример показывает...

PS Попробовал, session_set_save_handler не спасает. Хоть скрипт срабатывает сразу, тяжеловесный скрипт потом нафиг затирает эту дату, установленную тем кто выполнился паралельно :(

> 3. И это типа разумно? Лочить файл и "пусть весь мир подождет"?
А это типа разумно, держать сессию открытой, когда она уже ненужна?
А если она нужна? Как я столкнулся с проблемой: клиент ajaxом переодически опрашивает сервер (php) на предмет разной информации. Какие-то ответы приходят быстро, какие-то медленно. Все серверные обработчики запросов используют сессии. Если раньше я ее открывал в начале файла и забывал и был счастлив , то теперь у меня появился новый гимр на тему "закрыть ее перед долгим вычислением, потом открыть заново", иначе придется каждый раз дожидаться окончания выполнения тяжелых скриптов. Что мне на фиг не нужно:(

-~{}~ 26.07.08 04:03:

В общем-то, я думаю, что все яcно: если необходима не "транзакционная" модель работы с сессиями, то нужно писать свои функции что-нибудь типа session_online_write($name, $value) и session_online_read($name, $value). :(
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
никто не мешает открыть сессию заново, после ожидания:
запустить, взять данные, закрыть, подождать, открыть опять, записать результаты

-~{}~ 27.07.08 18:33:

Сессия - не "информационное облако", это всего-лишь интерфейс к файлу, который открывается с лочкой на запись.
сам по себе php не лочится, просто когда 2й процесс (скрипт) делает системный запрос на открытие файла - система его подвешивает и ждет освобождения ресурса.
Не нравится - напиши свои сессии, как тебе удобно.
 
Сверху