関数myflock マニュアル

(The documentation of function myflock)

Last Update: 2021/12/1


◆機能・用途(Purpose)

ファイルを書き込み用のモード("w","a"など)で開いて 排他ロックを掛ける。
Open a file with a writing mode (e.g., "w" or "a") and apply an exclusive file lock.


◆形式(Format)

#include <file.h>
inline FILE ∗myflock (const char ∗filename,const char ∗mode)


◆引数(Arguments)

filename 開くファイル名。
The name of the file to open.
mode 開くモード。 関数fopenの第2引数と同じであるが、 利用可能なモードは下記のものに制限される。
The mode to open, which is same as the 2nd argument of function fopen. However, available modes are restricted to the following ones:
  • 読み込みモード(Reading modes): "r+", "r+b", "rb+"
  • 書き込みモード(Writing modes): "w", "wb", "w+", "w+b", "wb+"
  • 追加書き込みモード(Adding modes): "a", "ab", "a+", "a+b", "ab+"
なお "w", "wb", "a", "ab" の4つのモードについてのみ動作チェック済みである。 すなわち読み書き兼用のモード ("r+", "w+", "a+"など)については 動作未チェックであり、これらの使用は強く非推奨とする。
Note that this function has been checked for only the following four modes: "w", "wb", "a", "ab". This means that no check has been done for mixed reading/writing modes (e.g., "r+", "w+", "a+") and thus using these modes is strongly discouraged.


◆戻り値(Return value)

開いたファイルのファイルポインタ。
The file pointer to the file opened.


◆使用例(Example)

FILE ∗fp=myflock("file.txt","w");


◆補足(Additional remarks)

  1. 既にファイルが別のプロセスによってロックされている場合は ロックが外れるまで待つ仕様になっている。
    If the file is already locked by another process, the function waits until the lock is released.
  2. この関数を用いるためには環境変数FILE_LOCKの値が設定されている必要がある。 FILE_LOCKの値としては以下のものが可能である。
    To use this function, an environmental variable FILE_LOCK has to be set. Available values of this variable are as follows.
    上記以外の値が設定されている場合や環境変数FILE_LOCKの値が設定されていない場合は エラー終了となる。 なおymaeda_opentoolsの初期設定手順にしたがって $YMAEDA_OPENTOOL_DIR/share/initall.bashrcまたは $YMAEDA_OPENTOOL_DIR/share/initall.cshrc を読み込むようにしてあれば環境変数FILE_LOCKの値が 設定されているはずである。
    If other values are set, or the environmental variable FILE_LOCK is not set, the program finishes as an error. Note that the environmental variable FILE_LOCK should already be set by reading $YMAEDA_OPENTOOL_DIR/share/initall.bashrc or $YMAEDA_OPENTOOL_DIR/share/initall.cshrc based on the initial setup procedures of ymaeda_opentools.
  3. ファイルを読み込みモードで開いて排他ロックを掛けたい場合は
    FILE ∗fp1,fp2;
    fp1=myflock("file.txt","a");
    fp2=fopen("file.txt","r");
    のようにすれば良い。
    To open a file by the reading mode and apply an exclusive file lock, use the following procedures:
    FILE ∗fp1,fp2;
    fp1=myflock("file.txt","a");
    fp2=fopen("file.txt","r");
  4. 関数CKfopen(functions_with_errcheck.h)を用いれば 読み込み、書き込み、追加書き込みのいずれのモードに対しても 一発で排他ロックを掛けることができ、 上の例のような読み込みモードでの2行の記述は不要である。 したがって通常はCKfopenを用いれば良く、 ユーザが関数myflockを直接利用する場面はあまり無いと思われる。
    Using function CKfopen (functions_with_errcheck.h), the exclusive file lock can be applied to all the reading, writing, and adding modes, without the redundant expression for the reading mode shown by the example above. Therefore, users should usually use CKfopen instead of myflock.
  5. この関数はCKfopenの内部で用いられている。
    This function is used internally by CKfopen.


◆関数内部でのコーディングに関する説明 (A description for the internal coding of this function)

一見してコードはやや長く複雑に見えるが、中核となるのは以下の部分である。
Although the code looks long and complicated, the following code is the core part.

while(1){
    fp=fopen(filename,mode);
    if(fp!=NULL){
         if(filelock_enabled==′y′){
             stat(filename,&file_stat);
             chmod(filename,file_stat.st_mode|S_ISGID);
        }
        lockf(fileno(fp),F_LOCK,0);
        break;
    }
}

この中で青字で示した部分が「排他ロックを掛ける」処理であり、 緑で示した部分が 「他のプロセスによってロックされている場合はロックが解除されるまで待つ」 処理になっている。 fopenがNULLを返すのはファイルのオープンに失敗した場合であり、 "w"や"a"などの書き込みモードでこれが起きるケースとしては
  1. ファイルを開くパーミッションが無い
  2. ディスク容量が満杯である
  3. ファイルへのパスが存在しない
  4. ファイルが既に別のプロセスによって排他ロックされている
が考えられる。このうちの1はユーザが自分自身のディレクトリで作業する分には 起きるケースは少ないと思われ、2も滅多に起きない。 3はこの関数の呼び出し前に関数pathcheckを実行することで回避できる。 したがって残るは4であり、 fopenが失敗するのは4に起因するという想定で 成功する(ロックが外れる)まで待つコードになっている。
The blue part shows processings to apply the exclusive file lock, while green does processings to wait until the file lock by another process is turned off. The function “fopen” returns NULL if opening the file failed which, for opening modes (e.g., "w" and "a"), may occur in the following cases:
  1. there is no permission to open the file;
  2. the disc is full;
  3. there is no path to the file; or
  4. the file is already locked by another process.
However, the case 1 is considered rare as the users usually do works under their own directories, and the case 2 is also considered rare. The case 3 can be avoided by calling function “pathcheck” in advance to this function call. Then NULL would be returned in the case 4. For this situation, the code above means that the program waits until the file lock by another process is turned off.