検索条件
全1件
(1/1ページ)
これだからWindowsは……。
use Fcntl; my $fh; sysopen($fh, "test.txt", O_CREAT | O_RDWR) or die; flock($fh, Fcntl::LOCK_SH()); flock($fh, Fcntl::LOCK_EX()); close($fh);
Linuxなどでは、共有ロックが排他ロックに切り替わるのですが、Windows上では切り替えることができず*1、そのままブロッキングされてしまいます。
use Fcntl; my $fh; sysopen($fh, "test.txt", O_CREAT | O_RDWR) or die; flock($fh, Fcntl::LOCK_SH()); truncate($fh, 0); # ファイルサイズを 0 に seek($fh, 0, 0); # ファイルポインタを先頭へ print $fh "test!!\n"; close($fh);
こんなテストプログラムを走らせます。LOCK_SH以外は、ロックを伴うファイル操作ではよく行う処理です。
LOCK_SH(共有ロック)は本来ならLOCK_EX(排他ロック)ですが、前項で述べたとおりWindows環境ではとりあえず共有ロックで開いておいて後から排他ロックに変更できないので、そのような状況を想定してLOCK_SHで記述してあります。
さてこのプログラムを実行すると、Windows上では0byteのファイルが作成されます。ActivePerl(5.14)の問題かもしれませんが、truncateでのファイルサイズ指定がそのままclose()後のファイルサイズになります。
不思議なことに、LOCK_EX(排他ロック)に変更するときちんと中身のあるファイルが作られます。
use Fcntl; my $fh; sysopen($fh, "test.txt", O_CREAT | O_RDWR) or die; flock($fh, Fcntl::LOCK_SH()); seek($fh, 0, 0); # ファイルポインタを先頭へ print $fh "test!!\n"; truncate($fh, tell($fh)); # 現在の位置でファイル切り詰め close($fh);
そもそもLOCK_SH(共有ロック)状態で書き換えようとすると、以前のサイズよりも大きくならず、そもそも書き変えられないという謎のバグに当たりました。
詳細な発生条件は不明ですが、めんどうくさいので、Windowsの場合共有ロックではなく最初から排他ロックをかけることにしました。