Contents
- UNIX
- Windows
- サーバ
- プログラミング言語
- データベース
- プロトコル
- サービス
- オープンソース
- 規格・技術
- アプリケーション
- PC
- DEVICE
- その他(未分類)
お問合せ: メールフォーム
以下のような、flock の戻り値を受ける変数名を使いまわすコードは危険。
/** * flock バッドノウハウ */ $fp = fopen('lock', 'w'); flock($fp, LOCK_EX); : : // ↓これが呼ばれた瞬間、上部の`排他ロック'は解除されてしまう。。 $fp = fopen('hoge.txt', 'w'); : :
/** * lock.php * [usage] % php lock.php arg1 arg2 * [description] * 第一引数に与えられた変数名で fopen(書き込みモード) の戻り値を受け、 * ロックファイル「.lock1」に対して排他ロックを試みる。 * 5秒後、第二引数に与えられた変数名の変数に 123 を代入する。 * さらに5秒後、スクリプトが終了する。 */ <?php $$argv[1] = fopen(".lock1", "w"); if (flock($$argv[1], LOCK_EX)) { echo '$' . $argv[1] . ": .lock1 success\n"; } else { echo '$' . $argv[1] . ": .lock1 failure\n"; } sleep(5); $$argv[2] = 123; echo '$' . $argv[2] . " = 123\n"; sleep(5); echo "exit.\n"; ?>
/** * check.php * [usage] % php check.php * [description] * ロックファイル「.lock1」に対して、1秒おきにノンブロッキングモードで排他ロックを試みて、 * 結果を出力する */ <?php while (true) { $fp = fopen(".lock1", "w"); if ( ! flock($fp, LOCK_EX | LOCK_NB)) { echo ".lock1 failure\n"; } else { echo ".lock1 success\n"; } sleep(1); } ?>
--------------------------------------------------------- % php lock.php fp1 fp2 $fp1: .lock1 success $fp1 = 123 exit. ------------------------------------------- screen split - % php check.php .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 success ← lock.phpが終了したと同時に排他ロック成功 ---------------------------------------------------------
--------------------------------------------------------- % php lock.php fp1 fp1 $fp1: .lock1 success $fp1 = 123 exit. ------------------------------------------- screen split - % php check.php .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 failure .lock1 success ← 変数「fp1」が上書きされたと同時に排他ロック成功 .lock1 success .lock1 success .lock1 success .lock1 success .lock1 success ---------------------------------------------------------
fopen を受ける変数を上書きした場合、ファイルポインタがクローズしたとみなされ、flock による排他ロックも解除されると推測される。