デッドロックのテスト用コード

test_lock.php:

<?php
error_reporting(E_ALL);
$f = array();
$f[0] = null;
$f[] = fopen(“lock_1”, “r+”);
$f[] = fopen(“lock_2”, “r+”);
 
if(@intval($_SERVER[‘argv’][1]) >= 2){
$task = array(2, 1);
}else{
$task = array(1 ,2);
}
 
foreach($task as $n){
echo “Locking $n … “;
 
echo flock($f[$n], LOCK_EX, $t=true)? “OK”: “Fail”;
echo “\n”;
echo “waiting some seconds…”;
sleep (5);
echo “OK\n”;
}
echo “Finished!\n”;

実行:

$ php test_lock.php &
$ php test_lock.php 2 &

 
ひとつのみ起動した場合 Finished! と表示されますが、上のように並列で実行した場合は正しく動作しなくなります。
 
手元の環境では FreeBSD 6.2 と Windows XP SP2 の場合はデッドロックして固まり、Linux 2.4.21-50.ELsmp の場合は 2番目のロックに fail し、デッドロックにはなりませんでした。
 
参考:
– flock のモード切替え時の挙動は環境によって異なる[2008-01-08-1]