猫柳さん、
コマンドプロンプトでCGIを起動し、CTRL-C で止めたのと同じ終了のさせ方をしています(しているつもりです)。
タスクマネージャでプロセスを終了させるのと同じだと思います(。。違うかもしれませんが)。
メモリをある程度大量に確保してから永久ループになるようにCGIを作って(つまりそのCGIの中でメモリを開放するところは実行されないようにして)、それをコマンドラインで起動し CTRL-C で止めてみてください。 あるいは、タスクマネージャでプロセスを終了してみてください。 確保したメモリは開放されると思います。
もっとも、これでは「メモリリーク」にならないことの実証にはなりませんか(?)。。。
こんにちは、猫柳と申します。
日ごろからAnHTTPDを愛用させて頂いております。
ログを読んでいると、「更新ボタンを連打するとCGIプロセスが強制終了される」
とありましたが、これはどういう事でしょうか、
一般的な終了処理では無く、プロセスの削除が行われるのですか?
当方はDelphiで作成したWindowsアプリケーションをCGIとして使用しているのですが、
プログラムによってはメモリの開放コードが実行されず、
メモリリークを生じるという事でしょうか?
だとしたら大変な問題ですので、仕様の改善をお願いします。。
中田昭雄さんへ
なるほど、更新ボタンの連打は接続が切れるんですね。
ということは、他ユーザとぶつかった時のみCGIにロックがかかるのですね。
わかりました。
当面の間、単一スレッドで、ロックファイルを使用するのをやめます。
対応をよろしくお願いします。
どうもありがとうございました。
ゆいちゃんへ、
更新ボタンの連打は接続が切れるのです。
単一スレッドがはたらいていても、前に書いた通りで、接続が切れて強制終了します。
CGIのプロセスが強制終了することはファイルロックの有無とは無関係です。
AN HTTPD の単一スレッドというのは、CGIプロセスのロック(CGIプロセスが同時には起動しない)ですから、CGIプロセスが終了するかどうかには関係しません。
接続が切れたとき、つまり連打したとき、CGIの中でロックファイルを使っていればロックファイルは当然残りますね。
当面、単一スレッドで CGIの中でロックするのをやめればよいでしょう、という話です。
もちろん問題は残るので、最初に書いた通り、対応を考えます。
中田昭雄さんへ
接続が切れたときにロックファイルが残るのはわかります。
でもCGI起動がぶつかった時(たとえば更新ボタンを連打されたとき)
これは接続が切れたとは言わないのですよね。
もし、私が思うように接続が切れていないとしたら、
(A1)AN HTTPDがロック
(A2)CGIがロックファイル作成
(A3)CGIがロックファイル削除
(A4)AN HTTPDがロック解除
(B1)AN HTTPDがロック
(B2)CGIがロックファイル作成
(B3)CGIがロックファイル削除
(B4)AN HTTPDがロック解除
と順番に行い連打された回数だけ更新が行われるはずです。
(ロックファイル処理があっても正常終了するはず)
上記動作を確認してからロックファイル処理を削除しようと思っていました。
ところが現状(単一スレッドにチェックがついている)で
上記動作を行うと、
(A2)で作成されたロックファイルが残るのです。
ということは(A2)のあと強制終了されている(単一スレッドという機能が働いていない)
と思います。
よろしくお願いします。
ゆいちゃんへ、
単一スレッドでも接続が切れたときにCGIは強制終了しますが、CGIが終了すると AN HTTPD のロックは解除されると考えてもらえばよいと思います。
単一スレッドでCGIの中でロックファイルを作ると、
ひとつのCGI(A)は、
(A1)AN HTTPDがロック
(A2)CGIがロックファイル作成
(A3)CGIがロックファイル削除
(A4)AN HTTPDがロック解除
という順番で動きます。(A2)(A3)がCGIの動作で、(A1)(A4)は AN HTTPD の動作です。
アクセスが重なると一つ目をAN HTTPDがロックしているので、2番目の CGI(B)は一つ目が(A4)の解除まで終わってからその後、
(B1)AN HTTPDがロック
(B2)CGIがロックファイル作成
(B3)CGIがロックファイル削除
(B4)AN HTTPDがロック解除
と動くことになります。
更新などで(A2)までのところで接続が切れて(A)の CGI が終了すると、
(A1)AN HTTPDがロック
(A2)CGIがロックファイル作成
(A4)AN HTTPDがロック解除
となり、そのあと、
(B1)AN HTTPDがロック
(B2)CGIがロックファイル作成
と続きますが、(A2)でロックファイルが作られているので、(B)のCGIは既にロックされているとみなしてしまいます。
CGIの中のロックをやめれば、
(A1)(A4)(B1)(B4)
と動いてくれますから、単一スレッドにチェックを入れているのなら、CGIの中でのロックはしない方がいいわけです。
CGIが接続断のために強制終了しても競合はおきないという意味ですから、CGIの動作自体は中断されるので、そのことによる不具合はあると思います。
あとは、動作スピードも関係します。つまり、(A2)から(A3)までがあっという間に終われば、その間で終了する可能性はほとんどなくなりますから。
中田昭雄さんへ
一度にひとつのCGIしか動かさないとのことですが、
もうちょっと詳しく聞かせてもらってもいいでしょうか?
今回のように2回更新されようとするとどうなるのでしょう?
1回目の処理を正常終了してするのを待ってから
2回目の処理が走るという意味でしょうか?
私は上記かと思いました。
ところが現在のAN HTTPのオプション設定で
単一スレッドにチェックがついているのです。
現在の状態(ロック処理は残っている。)で
CGI起動中に”ブラウザの戻る”または接続を切断された場合ロックファイルが残る
のはわかります(そのためにロック処理を削除した方がいいという
アドバイスをしてくれたと思います)が、
CGI起動中にCGIを呼び出した場合、ロックファイルが残るのは
やはり単一スレッドにチェックがついていても
CGIにロックがかかっていない(1回目の処理が強制終了されている)ような気がします。
サーバ上で動かしているからこういう現象が起こるのでしょうか?
ネット上で確かめるのがよいのでしょうが
現在サーバはネットにつながっていないため確かめることはできません。
よろしくお願いします。
ゆいちゃんへ、
あるユーザの接続が切れても他のユーザとぶつからないとは言えません。
また、他のユーザとぶつかっても強制終了するというわけではありません。
ファイルやディレクトリをロックに使うCGIの場合にHTTPサーバがCGIを途中で強制終了させるのでは具合が悪いという話です。
とりあえずの対応としては、CGIでロックするのはやめて AN HTTPD のオプションで「単一スレッド」にチェックを入れるのがよいでしょう。
これは AN HTTPD側でロックをする(一度にひとつのCGIしか動かさない)という意味です。
接続が切れたCGIを強制終了しても強制終了と同時にロックがはずれます。
レスありがとうございます。
途中で更新するとCGIを強制終了する件ですが、
対応を考えていただけるそうでありがとうございます。
ブラウザが前の接続を切断するということは、他のユーザとぶつかって
強制終了することはないのですね。(まだ試していないので・・)
とりあえずは、
一度更新ボタンをクリックすると、処理が終わるまで
ユーザが操作できないようにしなければいけないということですね。
できるかどうかわかりませんが、ちょっと調べてみます。
(PERLをあまりよく知らないもので・・・)
それとキャッシュの件ですが、
次のバージョンで対応してくれるそうでありがとうございます。
なんか意見を取り入れてもらえてとてもうれしいです。
マイクロソフトのページを見ました。
丁寧な説明をしてくれてありがとうございます。
とりあえず、これをつかって対応してみようかと思います。
本当にありがとうございました。
ゆいちゃんへ、
1.
途中で更新する(あるいは中止するか他のページへ移る)と、ブラウザが前の接続を切断します。
AN HTTPD はブラウザから接続が切られると、それを検出し、エラーメッセージ
"Client Abort?- (1) detected during CGI/SSI process"
を出します。 その後 CGIプロセスを強制終了します。
CGIが途中で終了するとエラー500になるので、エラーメッセージ
"Error Response 500"
になりますが、エラー500をブラウザに応答しようとしても既に接続が切られているので、
"Error: Can't send error response header (500)"
となります。
ここで問題は、CGIプロセスを強制終了してしまうことです。 これはこれでその方がよいと思ってそうしたのですが、たしかにファイルを使うロックを使用している場合などはCGIプロセスが自分で終了するのを待つようにした方がよさそうですね。 対応を考えます。
2.
少し前のIEはなにがなんでもキャッシュしてしまったという記憶がありますが、最近のバージョンではそんなことはなさそうですね。
マイクロソフトの文書番号JP234067 「Internet Explorer でキャッシュを無効にする」
http://www.microsoft.com/Japan/support/kb/articles/JP222/0/64.ASP
やその関連ページをご覧になってください。
具体的には
IEのインターネット一時ファイルの設定で「ページを表示するごとに確認する」にすることや、
Expires: -1 や Cache-Control: no-cache のヘッダを CGI で出すことなどが関係すると思います。
私が自分で確かめればいいのですが、ちょっと時間がとれないので、ゆいちゃんも確かめてみてください。
Expires や Cache-Control については AN HTTPD の次のバージョンでは対応する予定でいます。
こんにちわ
中田さんにAN HTTPDについて2つ質問があります。
一つ目は
Windows上でCGI作業中にもう一度同じ処理をすると最初の処理を
途中でやめてしまい、2回目の処理を始めてしまいます。
詳しく話すと、
ファイルを更新するCGI使用していて内容はファイルをOpenする前に
ロックファイルを作成して多重アクセスを避けファイルを更新すると
ロックファイルを削除ようとしているのですが、ロックファイルを
作成しファイルを更新している最中に、もう一度、このCGIを起動すると、
ファイルを更新せずにロックファイルだけが残ってしまいます。
おそらく、最初の更新処理中に処理を途中でやめてしまい、
2回目の処理を始めてしまっているようです。
CGIを起動する方法は、CGIで作成された更新ボタンからの起動となります。
(ブラウザの戻るを押しても処理を途中でやめてしまいます。)
その際、errors.logには以下の記述がありましたがどういう意味かは・・・
---------------------------------------------------------------------------連続でCGIを実行した時に最初の処理を終了してから、次の処理を実行する方法が
Thu May 16 10:06:07 2002 Client Abort?- (1) detected during CGI/SSI process
Thu May 16 10:06:07 2002 Error Response 500 Thread 0(ID= 1924) to 127.0.0.1 for "/cgi/point/point.cgi"
Thu May 16 10:06:07 2002 Error: Can't send error response header (500) for Thread 0 (ID = 1924) with errorcode 10054 for socket 444
-----------------------------------------------------------------------------