「ほっ」と。キャンペーン

<   2007年 10月 ( 4 )   > この月の画像一覧

昨日は妹が出産したので、病院にお見舞いに。
義弟と両親が来ていた。
行ったときは麻酔の切れかけで、
痛みでまったく喋れない様子だった。
麻酔がかかっている間って、痛み止めを入れづらいんだって。
入れづらいってのがどういう意味かはわからないけど、
お医者がそう言ってた。
なわけで、痛くて体が震える…とか言いながら
手術室から戻ってきたらしい。
麻酔が切れてから痛み止めを入れたわけで、
まだ効いていなかったようだ。
土気色の顔で、眉間にしわを寄せて痛みにたえていて、
私が近づいても全く気づかない様子だった。
出産というのはこんなにも命懸けで、
それでも産みたいと思う母親の一途な思いがあって。
妹を見ながらそんなことを考えて、目が潤んできてしまった。

生まれる数日前まで、
体重が1900gから増えないと心配されていた。
なんか病気でもあるんちゃうんか、とか。
妹がやっぱり一番心配していたようで、
無事に生まれてきた甥っ子を見て、
安心して泣いていたそうだ。
生まれてみたら、2276g もあって、髪の毛もフサフサだった。
吸引したのか、頭は縦長だったけどw
母によると、私は 2760g で生まれたのだが、
私は骨がわかるほど痩せてガラガラで
およそいわゆる「ぷくぷく赤ちゃん」とは程遠くて、
おまけにモサモサと毛深くて、
あんまり可愛くなかったらしい(笑)
そんな私よりも体重は少ないのに、
甥っ子は私よりもぷくぷくらしい。
良かった良かった(^-^)
(おくるみに包まれていたので、私はそのぷくぷく具合を知らない)。

見たところ、妹に似ている。
鼻とか上唇とか。
美少年ではないが、愛嬌のある顔立ちになるだろう。
ま、生まれて2-3時間で、
どっちに似てるもあったもんじゃないけど(^^;;

甥っ子の名前はもう決まっているのだそうだ。
義弟に聞いたところ「ハルトくん」だそう(勿論、漢字だけど)。
いい名前だね。
良い子に育っておくれ。

一緒にポケモンとかやれるといいな。

そのうち一人でウチにお泊りに来たりするといいな。
今から準備しておこうか。

あと30年くらいしたら結婚式に出たりするんだろうか。
席次に、新郎伯母、なんて書かれたりして。

既にオババカになりつつあったりする(笑)
[PR]
by xiaoxia | 2007-10-11 20:47 | 主婦 | Comments(0)

甥っ子が産まれるでちゅ

今日は妹の出産である。
なんで出産の日がわかるかというと、
帝王切開になったからである。
なんで帝王切開になったかというと、
母曰く「胎盤が入り口近くにあるんですって」ということなので、
前置胎盤なのだろう
(ゼンチタイバンでは私にはわからないかと、易しく言ってくれたのかも)。

兄弟姉妹は妹一人しかいなくて、
妹の初めての子どもなので、
私にとっても、初の甥っ子である。
ちなみに、もう男の子とわかっているらしい。
モノを揃えるために聞いたそうだ。
初めての子どもというのは、聞かないで楽しみにしているものかと思っていたが、
そんなあたりがサバサバした妹ぽくて面白い。

出産の時、病院に行っても良いかどうか、
ちょっと悩んだ。
妹のダンナは長男で、次男は未婚。
親戚は女の子ばっかりで、
あちらにとっても初孫であるばかりでなく、
待望の男の子らしい。
なわけで、あちらのご両親も来て大賑わいじゃないかと思ったわけで、
そこで姉なんてのがいても良いのかと、ちょっと悩んだわけ。

1週間ほど前に母に「行ってもよいものかねぇ」とメールしたら、
妹から「是非来てくれ」と返事。
有難う、行かせていただくよ。

このところ忙しくて、休日出勤などしていたのだが、
この日に定時退社するためだった、というのもある。
どうにも間に合わなそうで、行けないかと思っていたのだが、
今日の午前になって、突然サクサクと終了。
すごいぞ、オレ!
てっきり無理だと思っていたから、
カメラを持ってこなかった。
それだけが悔やまれる。むぅ。

というわけで、突然病院に行けることになりましたので、
これから行って来ます。
そろそろ退社します。
待ってておくれ、甥っ子よ(笑)
[PR]
by xiaoxia | 2007-10-10 17:51 | 主婦 | Comments(0)

[Perl] セマフォいじり

linux 上の Perl でセマフォをいじる羽目に。

既存の C のプログラムへの機能追加である。
通常、こういうことをしたいなら、C で書いた方が良いわけなのだが、
既存プログラムはテストに数ヶ月も費やした、素晴らしく大きなシステムである。
もう結合テストが終わっているので、
これから新機能を追加すると、テストをし直さなければいけない。
そんな工数は取れるはずもなく、
簡単に何とかなる Perl で、ちょちょっと。ここはどうかひとつ。と頼まれた。

以下の2つのページを参考にした。
ソフト開発塾 Linux Perlでの排他制御 その4
Perl のプログラミング・メモ セマフォ

ところが、どうも上手く取得できない。
セマフォ自体の作成はできているぽいんだけど。
perl からは直接 C の構造体の中身が見られないので、
一体何が起こっていて、どんな設定になっているのやら、
どうにもこううにも非常にカッカソウヨウ。
仕方なくロックファイルを作って、flock 2 で代用。
なんかカコワルくてイヤだなぁ、うーん。
と思いつつ、終電に追われて帰宅。
しかし、翌日の午前にひょっこり動いてしまった(゜ロ゜〃)
前日、なんで動かなかったのか、全然わかんない(´・ω・`)
ま、よ く あ る こ と ってやつか。

で、詳細に解説を入れてみる。
use IPC::SysV qw(IPC_CREAT IPC_EXCL SETVAL);

# 初期化
sub seminit {
  my ($key)=@_;

  my $semid = 0;

  # semget(KEY, NSEMS, FLAGS)
  # NSEMS 個のセマフォからなる新しい集合を作成(存在チェック)
  # FLAGS には、IPC_CREAT IPC_EXCL IPC_NOWAIT など
  # 定義値は /usr/include/linux/ipc.h を参照(以下3行引用)
  # #define IPC_CREAT 00001000  /* create if key is nonexistent */ = 512
  # #define IPC_EXCL  00002000  /* fail if key exists */ ......... = 1024
  # #define IPC_NOWAIT 00004000  /* return error on wait */ ....... = 2048
  $semid = semget($key, 1, 03600);       # semaphore作成

  # ↑思うにこの 第3引数の 03600 は、
  # IPC_CREAT、IPC_EXCL、0600(ownerだけrw)の or を取った数値(8進)なのかな

  # 新規作成する
  if (defined($semid)) {

    print STDERR '新規作成するよ!', "¥n";

    # semctl(ID, SEMNUM, CMD, ARG)
    # SETVAL => /usr/include/linux/sem.h を参照(以下の行は引用)
    #  #define SETVAL 16    /* set semval */
    # SEMNUM 番目の semaphore に ARG(1) を設定
    my $rc = semctl($semid, 0, &SETVAL, 1);  # semaphore の値を設定

    # 最初の人が semaphore に 1 を立て、その 1 をみんなで取り合う
    if (! defined($rc)) {
      print STDERR ("SETVAL 失敗 : $!¥n");  # 新規作成失敗
      $semid = 0;
    }
  }

  # 新規作成しなかった(既存だった)
  else {

    print STDERR '既存だった', "¥n";

    # semget(KEY, NSEMS, FLAGS)
    # 第2引数が 0 ならセマフォ集合を作らない
    $semid = semget($key, 0, 0);       # 既存のsemidを取得

    if (defined($semid)) {
      print "既存のを取得 SEMID = $semid¥n";
    } else {
      print STDERR ("既存の取得に失敗 : $!¥n");
      $semid = 0;
    }
  }
  return $semid;
}

# 取得
sub getSem {
  my ($semid)=@_;

  # pack("sss", $sem_num, $sem_op, $sem_flag)
  # semop 構造体の pack
  my $op = pack("sss", 0, -1, 0);

  # semop(KEY, OPSTRING)
  my $res = semop($semid, $op);

  return $res ? $res : 0 ;
}

# 開放
sub releaseSem {
  my ($semid)=@_;

  # pack("sss", $sem_num, $sem_op, $sem_flag)
  # semop 構造体の pack
  my $op = pack("sss", 0, 1, 0);

  # semop(KEY, OPSTRING)
  $res = semop($semid, $op);

  return $res ? $res : 0 ;
}


全部が終わるまで、開放はしちゃダメよ。
通常なら、この上に、開放を行う管理プロセスが必要なんだろうな。

以下のようなファイルを作ると、お試しができます。
例えば、立て続けに3つ起動しても、
ちゃんと3プロセス×10回の文字列が
1つのファイルに出力されるよん。
use IPC::SysV qw(IPC_CREAT IPC_EXCL SETVAL);
my $key = $<;             # uid を semid 作成のキーにしてみた
my $pid = $$;             # プロセス識別のため

print "$pid 開始¥n";
my $semid = &seminit($key);
my $res = 0;
my $fh;
sleep 3;               # 3つ起動するためにちょっと待ってみる
if($semid) {
  for($i=0 ; $i<10 ; $i++) {     # 10回まわしてみる
    $res = &getSem($semid);
    if($res) {
      # みんなでよってたかってファイルに書き込む
      open($fh, '>> semtest'); # エントリ登録エラー回避のためカッコが全角です
      print $fh "プロセスID $pid ... $i 回目書き込み¥n";
      close($fh);
      &releaseSem($semid);
    }
  }
}
print "$pid 終了¥n";


ちなみに、semaphore ができているかどうかの確認は
以下のファイルを見ればOK。
/proc/sysvipc/sem
[PR]
by xiaoxia | 2007-10-02 19:35 | プログラム言語 | Comments(0)

[perl] DBI のデストラクタ

ちょっと悩んだのでメモ。
1年以上前にハマったんだけど、
ネット上にあんまり情報がなかったので。

デストラクタのオーバーライドは不要


perl で PostgreSQL と通信。
なんだが、デストラクタでエラーが出る。
# エラーが出る
use DBI;
sub new {
  my($class) = shift;
  my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;
              $user,
              $passwd,
              { AutoCommit=> 1,
               PrintError => 1 }
  $dbh || (return 0);
  my $self = { 'DBH' => $dbh };
  bless $self;
  return $self;
}

sub DESTROY {
  my($self) = shift;
  $self->{'DBH'}->disconnect;
}

エラーメッセージはこんな感じ。
(in cleanup) Can't call method "disconnect" on an undefined value at myDB.pm line ** during global destruction.

オブジェクトの破棄前に閉じとこうって思ったんだけど、
disconnect しちゃいかんの?
と思ったら、先にスーパークラスの方の DESTROY が
自動的に呼ばれるらしい。
DBI - Database independent interface for Perl - search.cpan.org
ってことは、この内容なら、
DESTROY はオーバーライドしなくて良いわけね。

でも fork する時は自分で切断


実はこんな感じのプログラムを書いていたのだが、うまくいかない。
# うまくいかない
my $i = 0;
my $db = new myDBI;
$db->connect;
while(1) {
  my $pid = fork;
  if(defined $pid) {   # 子プロセス
   &hogehoge;     # DBアクセスはない関数
  }
  $i++;
  ($i==10) && last;
}
$db->select("select * from table");

最後の select 時に、DBI ハンドラが既に閉じてる、といわれる。
エラーメッセージはこれ。
DBD::Pg::st execute failed: server closed the connection unexpectedly at myDB.pm line ***.

$db->ping でステータスチェックをするようにして、
ping が返って来なかったら SQL 文を実行しないようにしたけど、
ぜんぜん根本的解決になってないわねー(笑)

で、原因は何だろうと思ったら、
fork すると、子プロセス終了時にデストラクタが呼ばれて、
ハンドラを閉じてしまうことだった。
えー、子プロセス中で DB 使ってないのにー!と思うのだが、
子プロセス中からハンドラにはアクセスできてしまうので、
アクセスできるハンドラは全部閉じちゃう、という仕掛けなのだろう。
まぁそうだよなぁ。
その気の利かせ方(時に余計)が、perlの良いところ(時に悪いところ)なんだし。

なわけで、解決策。
# 解決策
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;
            $user,
            $passwd,
            { AutoCommit=>1,
              PrintError=>1,
             InactiveDestroy=>1 }      # ←これを入れる
           );

connect 時のオプションを追加。
これをすると、デストラクタによるハンドラの自動破棄が行われない。
当然ながら、親プロセスでの自動破棄も行われないので、
明示的に disconnect しないとね。

へぇ、こんな仕掛けになってたのかー。
[PR]
by xiaoxia | 2007-10-01 18:48 | プログラム言語 | Comments(0)

ダメ女プログラマ&主婦&腐女子&バイオリン弾き


by 小霞