# ★【多重ロック サブルーチン】 と、 必要な 【初期設定】 # 【ご注意】 # あなたのCGIに組み込んだ時、このテキスト内の【多重ロックサブルーチン/初期設定】と # 組み込む前のあなたのCGI とで、 # 変数名の重複・サブルーチン名の重複 が無いようにして下さい。 # ※組み込む前のあなたのCGI内の ロックサブルーチン・ロック解除サブルーチンは # この【多重ロック サブルーチン】と置き換える事になります。 # この作業の要領は、【how_to_use_myLocking.htm】に説明してあります。 # 【how_to_use_myLocking.htm】内の # 【ご使用の CGI に組み込まれている ロック処理】 との兼ね合い と言う部分を読んで下さい。 #------------ 初期設定 -------------# # ロック形式 1=flock関数 2=symlink関数 それ以外の数値=mkdir関数)( 1 が望ましい。サーバー次第。) $lockkey = 1; # ◆◆↓ 扱うデータファイルによって、flock/symlinkを使い分けるための【ロック形式】の設定。 # (symlink用ロックfileは、別フォルダを使用。) # # ◆↓ 上の $lockkeyで設定できる値を選んで、好きな値(ロック形式)を設定する。 # ↓ すると、プログラムコードで【$SymYesNo = $SymUsable;】を設定している間だけ $SymUsableで選択した形式でロックされる。 $SymUsable = 1; # ◆↑ symlinkを一時的に【共用】で使うなら、$SymUsableに 2を設定する。 # ◆◆その場合は、全CGIで $SymUsable = 2; を設定するべし(そうしないと 別種CGI同士のロックが効かない)◆◆ # -------------------------------------- # ◆↓全CGIで共通のロックファイル名・・◆【サブルーチン(lock・unlock)の第2引数】 # # ◆【注意】 “データファイル実体 と ロックファイルの組み合わせ”を、全CGIで統一させないと、ロックが無効となる。 # # ◆作動させる前に、サーバーに ロックディレクトリを作成して下さい。 # (ロックファイルを存在させるディレクトリ ↑) # ロックディレクトリのパーミッションは【777】か【707】に設定します。(どちらでも動作すれば【707】) # # ※パーミッション設定は、サーバーによって微妙に違います。 # ※【“書き込まれるファイル”が存在するディレクトリ】のパーミッションは、大体 【777 or 707】です。 # その親ディレクトリのパーミッションは、 # “書き込まれるファイル”が 親ディレクトリ自身に存在しないなら 【755 or 705】で充分。 # $Sym_IP0_lockfile = '/export/members/hogehoge/mySight/cgi-bin/MunyaSymDir/SymSym_IP0_lock.lok'; $Sym_IP1_lockfile = '/export/members/hogehoge/mySight/cgi-bin/MunyaSymDir/SymSym_IP1_lock.lok'; $Sym_IP2_lockfile = '/export/members/hogehoge/mySight/cgi-bin/MunyaSymDir/SymSym_IP2_lock.lok'; $Sym_0_lockfile = '/export/members/hogehoge/mySight/cgi-bin/MunyaSymDir/SymSym_0_lock.lok'; $Sym_1_lockfile = '/export/members/hogehoge/mySight/cgi-bin/MunyaSymDir/SymSym_1_lock.lok'; $Sym_1i_lockfile = '/export/members/hogehoge/mySight/cgi-bin/MunyaSymDir/SymSym_1i_lock.lok'; $Sym_2_lockfile = '/export/members/hogehoge/mySight/cgi-bin/MunyaSymDir/SymSym_2_lock.lok'; # ここまでのロックfileは、symlink用ディレクトリを指定。 # symlink以外のロックにも使えるが、 # ◆いったん稼動開始したロック方式を 後で変更する場合は、flock形式で作成されたファイル名と重複しないように ↑ 変更すべし。(全CGI 共通) # ◆理由 ↓ ◆ # ◆flockのロックファイルは、その度に削除されない。(ディレクトリとファイルの名前重複の共存も不可。) # ◆flockは、使用中である事を 他の“flockを使うプロセス”に知らせるだけで、 # flockを使わないプロセスをロックすることは出来ない。 # ただし、flockは 高速で確実なロックが出来る。 $mini_IP0_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/mini_IP0_normal.lok'; $mini_IP1_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/mini_IP1_normal.lok'; $mini_IP2_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/mini_IP2_normal.lok'; $mini_0_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/mini_0_normal.lok'; $mini_1_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/mini_1_normal.lok'; $mini_2_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/mini_2_normal.lok'; $mini_i_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/mini_i_normal.lok'; $mini_f_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/mini_f_normal.lok'; $pwFile_pre_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/pwFile_pre_lock.lok'; $pwFile_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/pwFile_lock.lok'; $cokSrc_pre_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/cokSrc_pre_lock.lok'; $cokSrc_i_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/cokSrc_i_lock.lok'; $cokSrc_f_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/cokSrc_f_lock.lok'; $Bigger_lockfile = '/export/members/hogehoge/mySight/cgi-bin/NormalLockDir/Bigger_lock.lok'; # ---- (ここまで、ロックファイル名) ---- # ◆ ロック形式の使い分け方(一時的に symlinkを使う場合) # $SymYesNo = $SymUsable; # ← ◆一時的に、symlinkロック(2)を指定できる。 # $Sym_IP0_LK = &lock($otherGuard, $Sym_IP0_lockfile); # $SymYesNo = $lockkey; # ← ◆symlink指定を解除。 # # $SymYesNo = $SymUsable; # ← ◆symlinkロック解除を指定。 # &unlock($mylockOFF, $Sym_IP0_LK); # $SymYesNo = $lockkey; # ← ◆symlink指定を解除。 # このCGI専用ロックファイル名 (ログ用) $lockfile = './onlyAnalysisLOC/analysisLog.lok'; # このCGI専用ロックファイル用の【サブルーチン戻り値変数】 $pastCNTmin_LK =0; # ◆ロックファイル自体は、転送の必要なし(作成してはダメ)・・自動作成され 自動削除される。 # (転送時に作成すべきなのは、ロックディレクトリ だけ。) # ◆ ↓ flock用のロックアクションモード・・【サブルーチン(lock・unlock)の第1引数】(変更してはならない) # # ◆symlink/mkdir関数 の場合も、ダミーで“引数設定”するべし。 # ◆unlockを呼ぶ時の 第1引数は、必ず $mylockOFF (即ち 8)。 $otherReadOK = 1; # ← ★【共有ロック(1)】を使うと、多重ロック不可能。 $otherGuard = 2; $mylockOFF = 8; # 1 =共有ロック(他者の読み込みを許す) 2 =排他ロック(読み書き禁止) # 8 =ロック解除 # ◆flock検査を使って、「 1,2,4,8 」以外の値が表示されるサーバーでは、flock関数を使わない方が無難。 # ◆【 1 共有ロック】を設定しても、 # 現状の lockサブルーチン では、【flockロック】の場合は、競合プロセスは 同時に読めない。 # ◇理由◇: # “データfileに対する直接の 共有ロック”を行っておらず、 # 【ロックファイルを 上書きモードで開けるか?】によってロックの可否を判断し、 # 上書きモードで開けたら、flockで ロックファイルを共有ロックに設定する。 # 従って、 競合プロセスは、ロックファイルを読めても 上書きモードで開けないので、データfileを読めない。 # (改良の余地) # -------------------------------------- # ◆ ロックファイル名 とペア(組み)となる【サブルーチン戻り値変数】 $Sym_IP0_LK =0; $mini_IP0_LK =0; $Sym_0_LK =0; $mini_0_LK =0; $pwFile_pre_LK =0; $pwFile_LK =0; $Bigger_LK =0; $Sym_1i_LK =0; $mini_f_LK =0; $cokSrc_pre_LK =0; $mini_i_LK =0; $cokSrc_i_LK =0; $cokSrc_f_LK =0; $Sym_IP1_LK =0; $Sym_IP2_LK =0; $Sym_1_LK =0; $Sym_2_LK =0; $mini_IP1_LK =0; $mini_IP2_LK =0; $mini_1_LK =0; $mini_2_LK =0; # もし、使用するロックファイルの数を増やした場合は、↑ここに 【サブルーチン戻り値変数】の記述を追加する。 # (20もあれば足りるでしょう) # その場合は、 ALLUnLockサブルーチン の【numberList_of_array配列】に これ↑と同名の【戻り値変数】の名前を # 【numberList_of_array配列】の要素として 記述を追加する。 # -------------------------------------- # ここまで、【多重ロック】に必要な初期設定 # #--------------------------------------------------# # =============================== # ◆【ロック形式 初期値】の設定(通常設定) $SymYesNo = $lockkey ; $lockflag = 0 ; # ◆多重ロック処理で、$lockflagの値は 1か0ではなく、1プラスか1マイナスされる。 # -------------- $lockCount = 0 ; # ロック処理を行った“通算の回数” # -------------- # 【ファイルハンドル名】の初期文字列 $defHandle = 'LCK' ; $FileNumber = 0; # -------------- # 初期値 の設定 $Locked_File[0] = '' ; $Locked_Key[0] = 0 ; $Locked[0] = '' ; # =============================== # ============================================== # ============================================== ★★ 実際の処理での 【ロック処理・解除 サブルーチン】の呼び方 ※以下、ロック処理サブルーチンを【ロック処理ルーチン】と略称することもあり、 ロック解除サブルーチンを【ロック解除ルーチン】と略称することもあります。 ※以下、ロック処理サブルーチンを【lock】とも呼び、ロック解除サブルーチンを【unlock】とも呼びます。 # ============================================== ◆◆【ロック処理ルーチン】の呼び方 # ================= ◆【A方式】. 簡単なスタイルでの ロック処理ルーチンの呼び方 $Sym_IP0_LK = &lock($otherGuard, $Sym_IP0_lockfile); という形で呼びます。 $Sym_IP0_LK は、【lock】からの戻り値であり、【lock】から戻った時の戻り値が $Sym_IP0_LK に代入されます。 “【lock】を呼んだ時のロックファイル”のロックを あとで解除する時に、 【unlock】への“第2引数”として渡してやります。 (&unlock($mylockOFF, $Sym_IP0_LK); という形で ロック解除ルーチンを呼ぶ。) $Sym_IP0_lockfile は ロックファイルです。 $Sym_IP0_LK(戻り値変数)と 1対のペアになります。 この ロックファイル と 戻り値変数 の組み合わせは、固定的に決めてしまって下さい。 ※↑両方とも 変数名ですから、別の戻り値変数と組み合わせてもかまわないが、 “ネーミング上の対”が覚えやすい組み合わせが良い。 $otherGuard は、【lock】を呼ぶ時の“第1引数”で、これは必ず こうします。 ($otherGuard には 2 が設定されています) これは flock用のロックアクションモードですが、 flockを使わない場合でも、必ず “ダミー”で 第1引数に $otherGuard を指定して下さい。 &lock($Sym_IP0_lockfile); という記述で呼んでしまうと、ロックファイル名が “ロックアクションモードの引数”として認識されてしまいます。 # ================= ◆【B方式】. 一時的に ロック方式を変更するスタイルでの ロック処理ルーチンの呼び方 $SymYesNo = $SymUsable; $Sym_IP0_LK = &lock($otherGuard, $Sym_IP0_lockfile); という形で呼び、 【lock】から戻ったら $SymYesNo = $lockkey; として、ロック形式を 通常設定に戻しましょう。 ※一時的に ロック形式を変更する場合も、変更直後のロック形式は symlink形式でなくても構いません。 初期設定の先頭で、 $SymUsable = 1; となっている箇所で $SymUsable = 3; としておけば、 変更直後のロック形式は mkdir形式となるでしょ。 戻り値 と $otherGuard と ロックファイル指定については、A方式の説明と同様です。 (A方式と違うのは、ロック開始直前の【$SymYesNo = $SymUsable;】とロック開始直後の【$SymYesNo = $lockkey;】だけ) # ============================================== ◆A方式の場合も、B方式の場合も、 【lock】からの戻り値変数を 必ず 【ペアとなる unlock】への“第2引数”として渡してやります。 # ============================================== ◆【ロック解除ルーチン】の呼び方 &unlock($mylockOFF, $Sym_IP0_LK); という形で呼びます。 (A方式でロック処理した場合の【ロック解除ルーチンの呼び方】は、上記1行だけ。) 注意点【1】 A方式の場合も B方式の場合も、 【lock】を呼んだ時の“戻り値”を、必ず 【unlock】への第2引数で指定して下さい。← ★これは 重要です。 ★これを守って頂かないと、正しく動作しません。 注意点【2】 ロック方式を変更するB方式で【lock】を呼んだロック処理を 解除する場合は、 必ず、【lock】を呼んだ時のロック形式で【unlock】を呼びます。 ← ★これは 重要です。 つまり、 ★これを守って頂かないと、正しく動作しません。 $SymYesNo = $SymUsable; $Sym_IP0_LK = &lock($otherGuard, $Sym_IP0_lockfile); $SymYesNo = $lockkey; というB方式で【lock】を呼んだ場合のロック解除は、必ず 次のような記述で【unlock】を呼びます。 $SymYesNo = $SymUsable; &unlock($mylockOFF, $Sym_IP0_LK); $SymYesNo = $lockkey; これは、管理上 ちょっと面倒な点です。(だから、A方式のスタイルが楽です) その他については、A方式 と B方式 で 共通です。 【unlock】を呼ぶ時の 第1引数は、必ず $mylockOFF を指定して下さい。 これも flock用のロックアクションモードですが、 flockを使わない場合でも、必ず “ダミー”で 第1引数に $mylockOFF を指定して下さい。 # ============================================== ◆重要 :  これは、私のように、特定のデータファイルを“別種の複数CGIで共有して読み書き”する人への 2つの注意事項です。  [その1]  ロックファイル【あ1】 と データファイル群【あ2】 とを、“ペア”として固定的に組ませて下さい。  こうしなかった場合は、   (同一CGIを複数の人が同時に起動した時は ロックがかかりますが)  別種の2つ以上のCGIがほぼ同時に起動され、かつ その2つのCGIが 同一のデータファイルに読み書きした時は、ロックがかかりません。  つまり、  データファイル群【あ2】に 【CGI a】と【CGI b】が読み書きするのであれば、  【CGI a】においても 【CGI b】においても、  データファイル群【あ2】に読み書きする時は、必ず 同一のロックファイルを引数指定してロックします。     ※ロックファイル名(もしくは変数名)を、特定のデータファイル名(もしくは変数名)と似た名前にすると良いでしょう。  [その2]  【$SymYesNo = $SymUsable;】によって 一時的に 別種のロック方式を使い分けるならば、  同一のロックファイルに関しては、常に同一のロック方式で ロック開始/ロック解除を行うことが肝要です。   (詳しくは、how_to_use_myLocking.htm の【 $SymYesNo = $SymUsable; 】に関する説明 を読んで下さい。) # ============================================== ◆【多重ロック】のやりかた (A方式の場合も B方式の場合も、共通。) 2回か3回 続けて【ロック開始】を行うのですが、ロックファイル指定する引数で 別々のロックファイルを指定します。 ◇重要 : 下の 【ロック開始1】と【ロック開始2】とでは、 第2引数のロックファイル指定で 異なるロックファイルを指定してやります。 ロック開始1 ・・・ 戻り値1 = &lock($otherGuard, ロックファイル1); ロック開始2 ・・・ 戻り値2 = &lock($otherGuard, ロックファイル2); ファイル処理 ロック解除2 ・・・・・ &unlock($mylockOFF, 【lock】を呼んだ時の“戻り値2”); ロック解除1 ・・・・・ &unlock($mylockOFF, 【lock】を呼んだ時の“戻り値1”); ◇重要 : 【ロック開始1】の戻り値1を、【ロック解除1】実行時の第2引数として指定します。 【ロック開始2】の戻り値2を、【ロック解除2】実行時の第2引数として指定します。 ◇重要 : 【ロック開始】を行う時の第2引数(ロックファイル)は、 ロックされていないロックファイルを指定します。  (当然ですが) そのCGIスクリプト内で、自分がロック開始で指定した(まだ ロック解除していない)ロックファイルを指定して【ロック開始】を行うと、 ロックビジーとなって ロックがかかりません。 “他のプロセスのロック中”であれば、待つことによって ロックがかかるでしょうが、 自分がかけたロックであれば、いくら待っても ロックビジーです。(笑) ◇これ↓ は さほど重要ではありませんが、 ロック開始1 ロック開始2 ファイル処理 ロック解除1 ロック解除2 という順番での ロック開始〜ロック解除よりも、 ロック開始1 ロック開始2 ファイル処理 ロック解除2 ロック解除1 という順番の方が勝ります。 (つまり、外ロック+内ロック という考え方です。) # ============================================== ◆【ロック 全解除サブルーチン】の呼び方 &ALLUnLock; と、呼ぶだけです。 うっかり間違えて EachUnLockを呼ばないで下さい。エラーが起きます。 EachUnLockサブルーチンは、ALLUnLockからだけ 自動的に呼ばれるサブルーチンです。 ※間違えて EachUnLockを呼んだ場合の対策としては、 ALLUnLockから EachUnLockを呼ぶ時にフラッグを立てて EachUnLockの先頭でチェックすれば良いのですが、 横着して 手を抜きました。 # ============================================== ◆ロック開始 と ロック解除が 順不同に入り乱れても大丈夫です。 ◇“同一のロックファイル指定の ロック開始”を2回連続はしないで下さい。 ◇最初は ロック開始から始めて下さい。 ◇ロック解除を2回連続しても問題は起きません。($Locked[$unLockNumber] の値が 'yes'であるか検査している) ◇【analysis.txt】の、実際のロック開始部分を見て下さい。 if ($Sym_IP0_LK == 0) { &pictureView; } とか、 if ($mini_IP0_LK == 0) { &pictureView; } と、記述されている部分は ロックサブルーチンの戻り値の判定であり、ロック失敗(ロックビジー)の判定です。 この 戻り値判定は、 if ($lockbusy == 1) { &pictureView; } と記述しても同じであり、 その方が 簡潔です。 (そうすれば、ロックサブルーチンの戻り値の判定は どこで判定する時も 1種類の記述で統一できます。) でも、 私は、 エディターで $Sym_IP0_LK の文字列を選択〜F3キーを押した時に カーソルが大きく移動せず、 同一単語が色分けされるので、 &lock と &unlock の組み合わせで 【戻り値の対比】が一目瞭然なので、こうしています。 ◇また、 【analysis.cgi】は 隠しCGIなので、pictureViewサブルーチンに飛ばせていますが、 通常のCGIでは、ビジーメッセージを引数に持たせて【エラー処理ルーチン】に飛ばす形になるでしょう。 例えば、 if ($Sym_IP0_LK == 0) { &Errors("【ロックビジー】です。"); } という風に。 そして、エラー処理サブルーチン や 終了させるサブルーチンの先頭部分には、 次の1行を追加して下さい。 if ($lockflag != 0) { &ALLUnLock; } また、 正常に 所定の処理が完了し、終了させたり 別のプログラムに制御を移す場合も、 その直前に、 if ($lockflag != 0) { &ALLUnLock; } の1行を追加して下さい。 # ============================================== # ============================================== ★以上です。 あとは、下記のサブルーチンがあれば 動作します。 初期設定/初期値の設定/下記のサブルーチンで 使われている変数名 と 同一の変数名が あなたのCGIで使われているかどうか・・・ のチェックも必要ですが、 それは、【how_to_use_myLocking.htm】の中で 【名前空間】として詳しく説明します。 # ============================================== #/*---------------- 必要な サブルーチン -----------------*/ # ===================================== # # ◆ロック処理 # $LockAction …… ロックアクションモード・・【第1引数(flock用)】 # $LockingFile …… ロックファイル名・・・・・【第2引数】 # # ◆【戻り値】: # ロック出来なかった場合は、ゼロ(0) # ロック出来た場合は、 ロックした時の 【ロック処理履歴・情報-配列 の 添字ナンバー($lockCount)】(「何回目のロック処理か?」の値) # # ※【配列の特徴】: 同じロックfileでも、 成功すれば 単純に 情報を格納する(繰り返して)。 # $lockCountは ロックした通算回数。 # 【戻り値 $LockNumber】は、その時のロック処理が何回目であるか・・の数値。 # # ※戻り先で、 # 各々のロックfile専用変数 ↓ に、【そのロックfileを最後にロックした時の“添字ナンバー”】として # $Sym_IP0_LK などに代入する。 # ◇エラー時は、$Sym_IP0_LK 〜 $cokSrc_f_LK 等が、それぞれの 【戻り値 $LockNumber】の最新_添字ナンバーを保有。 # # # $LockHandle[$lockCount] …… ロックファイルの【ファイルハンドル(flock用)】 # # ↑ ファイルハンドルへのリファランス・・・(【作成したファイルハンドルの“型グロブ”】へのポインタ) # が代入され、保有する(flockロック成功時)。 sub lock { my $LockKey = $SymYesNo ; $lockbusy = 1; local ($LockAction) = $_[0]; local ($LockingFile) = $_[1]; # 180秒以上 古いロックなら削除(symlink・mkdirの場合) # ◆外部アクセスの処理では、時間を長く確保。 if (($LockKey != 1) && (-e $LockingFile)) { local($mtime) = (stat($LockingFile))[9]; if ($mtime && $mtime < time - 180) { if ($LockKey == 2) { unlink($LockingFile); } else { rmdir($LockingFile); } } } # ◆ flockでは、ロック中にプロセスがダウンしても自動的にロック解除される。 # 【ファイルハンドル名】を生成 (flock用) $FileNumber++; $NewHandle = "$defHandle$FileNumber" ; # LockBlockは ラベル LockBlock: { local($cnt) ; for ($cnt = 1; $cnt < 4; $cnt++) { if ($LockKey == 1) { # flockで ロック if (open($NewHandle, ">$LockingFile")) { if (flock($NewHandle, $LockAction)) { $lockflag++; $lockCount++; $Locked_File[$lockCount] = $LockingFile ; $Locked_Key[$lockCount] = $LockKey ; $Locked[$lockCount] = 'yes' ; $LockHandle[$lockCount] = \*$NewHandle ; #【型グロブへのリファランス】を代入。 $lockbusy = 0 ; last LockBlock; } else { close($NewHandle) ; sleep(1); } # ← flock出来ない場合 } else { sleep(1); next; } # ← open出来ない場合 (他のプロセスがロック中) } elsif ($LockKey == 2) { # symlinkで ロック if (symlink(".", $LockingFile)) { $lockflag++; $lockCount++; $Locked_File[$lockCount] = $LockingFile ; $Locked_Key[$lockCount] = $LockKey ; $Locked[$lockCount] = 'yes' ; $lockbusy = 0 ; last LockBlock; } else { sleep(1); next; } } else { # mkdirで ロック if (mkdir($LockingFile, 0755)) { $lockflag++; $lockCount++; $Locked_File[$lockCount] = $LockingFile ; $Locked_Key[$lockCount] = $LockKey ; $Locked[$lockCount] = 'yes' ; $lockbusy = 0 ; last LockBlock; } else { sleep(1); } } } } if ($lockbusy == 0) { $LockNumber = $lockCount ; } else { $LockNumber = 0 ; } return $LockNumber ; } # ===================================== # # ◆ロックを解除 # $unlockAction …【第1引数】・・ ロックアクションモード(flock用) # $unLockNumber …【第2引数】・・ ロック解除すべきロックファイルの、【ロック処理履歴・情報-配列 の 添字ナンバー】(「何回目のロック処理か?」の値) # # # $LockHandle[$unLockNumber] …… ロックファイルの【ファイルハンドル(flock用)】 # $Locked_File[$unLockNumber] …… ロックファイル # sub unlock { my $LockKey = $SymYesNo ; local ($unlockAction) = $_[0]; local ($unLockNumber) = $_[1]; if (($lockflag != 0) && ($Locked_File[$unLockNumber] ne '') && ($Locked[$unLockNumber] eq 'yes')) { if ($LockKey == 1) { flock($LockHandle[$unLockNumber], $unlockAction) ; close($LockHandle[$unLockNumber]) ; $lockflag--; $Locked[$unLockNumber] = 'free' ; # ロック解除の目印 } elsif ($LockKey == 2) { if (-e $Locked_File[$unLockNumber]) {unlink($Locked_File[$unLockNumber]) ;} $lockflag--; $Locked[$unLockNumber] = 'free' ; # ロック解除の目印 } else { if (-e $Locked_File[$unLockNumber]) {rmdir($Locked_File[$unLockNumber]) ;} $lockflag--; $Locked[$unLockNumber] = 'free' ; # ロック解除の目印 } } } # ===================================== # # ◆終了させる時の 【全ロック解除】処理◆ # sub ALLUnLock { if ($lockflag == 0) { return; } # 配列の各要素は、「特定ロックファイルの“最後のロック処理”が、通算で何回目のロック処理か?」の値を保有。 # (ロック処理履歴・情報-配列 の 添字ナンバー) $dummy_LK = 0; @numberList_of_array = ( $dummy_LK, $Sym_IP0_LK, $mini_IP0_LK, $Sym_0_LK, $mini_0_LK, $pwFile_pre_LK, $pwFile_LK, $Bigger_LK, $Sym_1i_LK, $mini_f_LK, $cokSrc_pre_LK, $mini_i_LK, $cokSrc_i_LK, $cokSrc_f_LK, $Sym_IP1_LK, $Sym_IP2_LK, $Sym_1_LK, $Sym_2_LK, $mini_IP1_LK, $mini_IP2_LK, $mini_1_LK, $mini_2_LK, $pastCNTmin_LK, $psIDwork, $LgdlchkGo, $pswCookREC, $psDateMgr, $dHjlIfI, $elHIjfItI ) ; # ◆配列の要素↑を追加する時、【最後の要素】の後ろには“カンマ”を付けては ↑ ダメ。 $ULK_Suu = 0; local $LetUnLock[0] = 0 ; foreach $locked_number (@numberList_of_array) { $n = $locked_number + 0; if (($n != 0) && ($Locked[$n] eq 'yes') && ($Locked_File[$n] ne '')) { $WiLLunLockNumber = $n ; $ULK_Suu++; $LetUnLock[$ULK_Suu] = $WiLLunLockNumber; # $LetUnLock[$ULK_Suu] は、アンロック対象の 新規_情報配列。 $WiLLunLockNumber は、【ロック処理履歴・情報-配列 の 添字ナンバー】 } } if ($ULK_Suu > 0) { &EachUnLock($ULK_Suu); } $lockflag = 0 ; # 各自アンロック不成功でも、強制的に $lockflag をゼロに。(仕方ない) } # ===================================== sub EachUnLock { # ALLUnLockからのみ呼ばれるサブルーチン。($lockflag = 0 ; は、親ルーチンで設定。) my($ULK_Suu) = $_[0]; for ($L = 1; $L <= $ULK_Suu ; $L++) { $ULKnumber = $LetUnLock[$L]; if ($Locked_Key[$ULKnumber] == 1) { flock($LockHandle[$ULKnumber], $mylockOFF); close($LockHandle[$ULKnumber]); $Locked[$ULKnumber] = 'free' ; # ロック解除の目印 } elsif ($Locked_Key[$ULKnumber] == 2) { if (-e $Locked_File[$ULKnumber]) {unlink($Locked_File[$ULKnumber]) ;} $Locked[$ULKnumber] = 'free' ; # ロック解除の目印 } else { if (-e $Locked_File[$ULKnumber]) {rmdir($Locked_File[$ULKnumber]) ;} $Locked[$ULKnumber] = 'free' ; # ロック解除の目印 } } } # ===================================== sub miniSleep { select(undef, undef, undef, 0.5) ; } # ===================================== #------------------------------# # エラー 〜 終了処理 (例) # ◆ご自分の エラー処理に合わせて調整されたし。 sub Errors { if ($lockflag != 0) { &ALLUnLock; } # ← 最低限、この1行は必要です。 @ErrMesse = @_; $ErrMesse[0] = 'システムエラー発生' if (!$ErrMesse[0]); $ErrMesse[1] = '原因不明のエラー発生 (強制終了)。' if (!$ErrMesse[1]); print 'Content-type: text/html' . $fcode . "\n\n"; print <<_ERR_HTML; $Title [エラー発生] ★ $ErrMesse[0] ★

$ErrMesse[1]

(エラーが発生し、処理を中断しました)


_ERR_HTML exit; } # =====================================