[PHP-users 30495] Re: session_start()から先に進まない

Reiji Matsumoto matsumoto @ spline.oc.to
2006年 10月 11日 (水) 18:11:20 JST


こんにちは。松本です。
前回は操作ミスで同じ記事を2回投稿してしまい、失礼しました。

> セッションを使っている場合の「スクリプトの終了」とは、具体的にど
> んな状態を指しますでしょうか。
あるURIにアクセスし、ページが完全に表示され、ブラウザの読み込みが
終了する状態の事を、そのように表現しました。

つまり、、、

-- 1.php ----
<?php
session_start();
sleep(30);
print "1.php complete.";
?>

-- 2.php ----
<?php
session_start();
print "2.php complete.";
?>

という2つのスクリプトがあったとして、同一セッションIDで
アクセスした場合、1.phpを開いたブラウザで"1.php complete."
と表示されてからでないと、2.phpを開いたブラウザで
"2.php complete."とは表示されないと言う事なんです。
1.phpがなんらかの事情で非常に長い間終了しないとしたら、
2.phpの処理は終了しませんので、そのような可能性かなと思
いました。

Firefoxなら別タブで1.phpと2.phpを開く事で、簡単にテスト
できます。IE6の場合は以下のようにしてみて下さい。

・まずIE6を1つ開き、1.phpを実行する。
・"1.php complete"と表示されたら Ctrl+Nを押し、別ウィン
 ドウを開く。新しく開いたウィンドウのステータスバーには、
 約30秒後に"ページが表示されました"と表示される。
・2つのウィンドウのステータスバーが同時に見られる
 ように、ウィンドウ位置を調節する。
・最初から開いていたウィンドウをリロードし、1.phpを
 もう一度キックする
・新しく開いたウィンドウのアドレスバーに30秒以内に
 "http://ドメイン/2.php"と入力し、2.phpを実行する。
・すると、2.phpにはウェイトが無いにも関わらず、ほぼ同時
 に新旧のウィンドウの読み込みが終了する

と、なると思います。

と言うわけで、同一セッションで起動しているスクリプトは、
同時に処理する事はできず、後から起動したスクリプトは
session_start()で待ってしまいます。ですので現象として
は本件に似ていると思うのですが、残念ながら、現状では
確実にこの問題に起因しているかどうかは、まだ分かりません。

> 松本様のご指摘は、言い換えると
> セッションファイルがロックされた後、そのまま長期間利用しないこと
> によりロック元のプロセス自身は存在しなくなり、再アクセスしたとき
> は違うプロセスが、自分がロックしたものと違うセッションファイルを
> 開こうとしている問題、
> と解釈してよろしいでしょうか。

いいえ。
セッションファイルがロックされた後、元のプロセスが存在し続ける
ために発生する問題です。プロセスが終了すればロックは解除され
ます。

> ロックが原因だとすると、「アクセスしてずっと待ってるとたまに開け
> る場合がある」のが気になります。
そうですね。。。
私の仮定を確認するには、httpdプロセスがオープンしている
ファイルを確認するのが良いと思います。
まずsession_start()で戻ってこなくなってしまったスクリプトの
セッションIDを調べます。これはブラウザのCookieを見たり、スニ
ファーやAchillesのようなユーティリティで可能です。次に、サー
バー側でhttpdがオープンしているファイルを調べます。これは
"lsof -c httpd"等で調べられます。
セッションIDに関連付けられたファイルをオープンしているhttpd
が2つ以上あるとしたら、1つは今ブラウザで開いているスクリプ
トで、もうひとつは何等かの理由で終了しきれていないプロセスの
可能性があり、私の仮定の可能性が高まります。

現状では雲をつかむような話しで、あくまでひとつの可能性という
レベルなのですが、各種調査が可能な環境でしたら一度試してみて
頂けたらと思います。





PHP-users メーリングリストの案内