PHPのDIO関数を使った排他制御の方法がお分かりの方教えてください。納得の行く回答をいただければ500pt進呈いたします。SolarisのNFS環境での記述で

$fh = dio_open($cntfile,O_RDONRY|O_TRUNC );
dio_fcntl($fh,F_SETLKW,array(”type”=>F_WRLCK));
$result = dio_write($fh,$cnt);
dio_fcntl($fh,F_SETLKW,array(”type”=>F_UNLCK));
dio_close($fh);

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:--
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答1件)

id:zizz_walla No.1

回答回数121ベストアンサー獲得回数0

ポイント500pt

排他制御の基本的な流れは

1.オープンする

2.ロックする

3.読み込む

4.書き込む

5.ロック解除する

6.クローズする

となります。

つまり、ご質問にかかれているサンプルの流れで基本的にはよいということになります。

・NFS環境での排他制御について

SolarisのNFS環境とのことですので、排他制御にflock()は使えず、fcntl()を使用する必要があります。

NFSサーバとクライアントがNetwork Lock Manager(NLM)プロトコルに対応していれば、NFS上のファイルに対してもfcntl関数を使って安全に排他制御を行うことができます。

・サンプルソースの記述ミス?

ご質問の例で dio_write()を使っているにもかかわらず

 $fh = dio_open($cntfile,O_RDONRY|O_TRUNC );

で、O_RDONRYとなっているのは書き間違いでしょうか。

 $fh = dio_open($cntfile,O_RDWR|O_TRUNC );

ですよね。リードオンリーモードで読み込んでいるにもかかわらず、dio_write()しているのでエラーになります。

・ロックする

 lock.l_type = F_WRLCK;

 lock.l_whence = SEEK_SET;

 lock.l_start = 0;

 lock.l_len = 0;

 fcntl(fd, F_SETLKW, &lock)

・ロック解除する

 lock.l_type = F_UNLCK;

 lock.l_whence = SEEK_SET;

 lock.l_start = (off_t) 0;

 lock.l_len = (off_t) 0;

 fcntl(fd, F_SETLKW, &lock);

php-4.3.10のソース(ext/dio/dio.c)をみてみると

ファイル全体を排他制御する場合、

ロックは

 dio_fcntl($fh,F_SETLKW,F_WRLCK);

ロック解除は

 dio_fcntl($fh,F_SETLKW,F_UNLCK);

と書くだけでいけそうです。(バージョンにもよると思いますのでご確認ください。)

・各パラメータ

start  省略すると 0

length 省略すると 0

whence 省略すると 0 (SEEK_SET)

 は、ファイルのある部分をロックするときに設定します。ファイル全体をロックする場合は、0,0,SEEK_SETを設定します。dio_fcntl()だと省略すればよいです。

type  省略すると 0

 は、どのような排他制御をするかを指定します。

F_RDLCK シェアードロック

F_WRLCK 排他ロック

F_UNLCK 上記ふたつのロックを解除

各パラメータの詳細は紹介したURLが詳しいのでそちらを参考にしてください。

・マニュアルの間違い

wenthとあるところは間違っています。dio.cではwhenceとなっていますのでご注意ください。

id:soyuz11

大変ありがとうございました。

教えていただいた通りに試してみたら、無事作動しているようです。

2005/01/27 10:11:55

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません