鈍足ランナーのIT日記

走るのが好きな5流のITエンジニアのブログ。

趣味の範囲は広いけど、どれも中途半端なクソブロガー楽しめるWebアプリを作ってあっと言わせたい。サーバーサイドPerl(Mojolicious)、クライアントサイドVue.js。Arduinoにも触手を伸ばす予定。

windows7(64bit)+cygwin環境構築ではまる

cygwinのインストールでabnormal exit: exit code=127

インストールすると、必ずこける。/etc/postinstall/cygutils.sh

/usr/bin/update-desktop-database
/usr/bin/update-mime-database /usr/share/mime

とりあえず、コメント化しておいた。動いているみたいだから、いいかぁ。。

Test::SharedForkのテストが終わらない

こちら にも報告されている既知の問題らしい。

01_simple.t(1/43)というところで止まってしまう。

そのテストだけ動かして見たけれど、まったく動かないというわけではなくて 途中でストップしている

 ok 1 - parent 1
ok 2 - child 1
ok 3 - parent 2
ok 4 - child 2
ok 5 - parent 3
ok 6 - child 3
ok 7 - parent 4
ok 8 - child 4
ok 9 - parent 5
ok 10 - child 5

親子の実行が混ざりあうとロックするような感じ。

子のsleepをコメントして、親のスリープを1秒固定にして、 子を先に実行させると全部のテストが通った。

その逆で親のsleepをコメントして、子のスリープを1秒固定にして、 テストを実行すると固まった。 CentOsの環境で同じようにして、テストしてもテストは通る。 cygwin以外のWindowsは大丈夫なのかな?

ソースを読もうとチャレンジするも、理解を超えていて、どうにかなるものではなさそう。

ということで、不本意ながら以下で回避。

cpanm Test::SharedFork --notest

結局Cygwinflockが問題

以下のようなソースをLINUXで動かすと 200行のaaaテキストが出力されるけれど、 Windows(cygwin)では処理が固まった。

use strict;
use warnings;
use Fcntl ':flock';

sub lock(){
    my $pid = shift;
    open(DAT, ">>/tmp/test.lock");

    flock(DAT, LOCK_EX);

    print DAT "aaa\n";

    close(DAT);

}

open(DAT, ">/tmp/test.lock");

close(DAT);

my $pid = fork();

if ($pid == 0) {
    # child
    lock() for 1..100;
} elsif ($pid) {
    # parent
    lock() for 1..100;
    waitpid($pid, 0);
} else {
    die $!;
}

perldocのflockを引用すると

*真の flock(2) に対応しているシステムではロックは fork() を通して 継承されるのに対して、より不安定な fcntl(2) に頼らなければならない場合、 サーバを書くのは本当により難しくなります。

予想としては、Cygwinは、flock(2)に対応していないシステムということなんではないかな。