FLOCK(2)

名前
flock - オープンされたファイルに対するアドバイザリロックの適用、解除を行う

書式
#include <sys/file.h>

int flock(int fd, int operation);

説明
オープンされたファイルにアドバイザリロック (advisory lock) の適用 や解除を行う。 ファイルは fd で指定する。引き数 operation には以下のいずれか一つを指定する:

    LOCK_SH
        共有ロックを適用する。 指定したファイルに対して、 一つ以上のプロセスが同時に共有ロックを保持することができる。

    LOCK_EX
        排他ロックを適用する。 指定したファイルに対して、 ただ一つのプロセスだけが同時に排他ロックを保持することができる。

    LOCK_UN
        このプロセスが保持している既存のロックを解除する。

flock() を呼び出したときに、指定したロック種別と異なるロックが別プロセスによって 保持されていると、 flock() は停止 (block) されることがある。 非停止 (nonblocking) タイプの要求を行うためには、 上記の操作 (operation) に LOCK_NB を論理和の形で指定する。 一つのファイルに共有ロックと排他ロックを同時に設定することはできない。 flock() によって作られるロックは、 オープンファイル記述 (open file description) (open(2) 参照) と関連付けられる。 したがって、ファイルディスクリプターの複製 (fork(2) や dup(2) などにより作成される) は同じロックを参照し、 これらのファイルディスクリプターのどれを使っても このロックを変更したり解放したりできる。 また、ロックの解放は、 上記の複数のファイルディスクリプターのいずれかに対して 明示的に LOCK_UN 操作を指示した場合か、これらのファイルディスクリプターがすべて 閉じられた場合に行われる。 あるプロセスが open(2) (もしくは同様の方法) を使って同じファイルに対して 複数のディスクリプターを取得した場合、 flock() はこれら複数のディスクリプターを各々独立のものとして扱う。 これらのファイルディスクリプターの一つを使ってファイルをロックしようと した際、そのロック要求は、呼び出し元のプロセスがそのファイルの別の ディスクリプター経由ですでに設定しているロックによって拒否される場合がある。 一つのプロセスは、一つのファイルに対して (共有ロックと排他ロックのうち) いずれか一種類のロックしか設定できない。 既にロックされたファイルに対して flock() を呼び出すと、既存のロックを新しいロックモードに変更することになる。 flock() により作成されたロックは execve(2) の前後で保存される。 共有ロックも排他ロックも、ファイルがどのモードでオープンされたかに 関係なく適用することができる。

返り値
成功した場合は 0 が返される。エラーの場合は -1 が返され、 errno が適切に設定される。

エラー

EBADF
    fd がオープンされたファイルディスクリプターではない。

EINTR
    ロックの獲得を待っている間に、ハンドラーにより捕捉されたシグナルを 受信し、 flock() が中断された。 signal(7) 参照。

EINVAL
    oepration が無効である。

ENOLCK
    ロックレコードを割り当てるためのメモリーが不足している。

EWOULDBLOCK
    指定したファイルがロックされており、 LOCK_NB フラグが指定されている。

準拠
4.4BSD (flock() コールは 4.2BSD で最初に登場した)。 fcntl(2) で実装されているものなどを含めると、 flock() の機能はほとんどの UNIX システムで実装されている。

注意
kernel 2.0 以降では、 flock() は、GNU C ライブラリでの fcntl(2) を呼び出してのエミュレーションではなく、 それ自体がシステムコールとして実装されている。 この実装では、 flock() と fcntl(2) で適用されるロックの種別には相互作用がなくなり、 flock() がデッドロックを検出しなくなる。 (ただし、最近の BSD などいくつかのシステムでは、 flock() と fcntl(2) ロックが互いに影響することが「ある」という点に注意すること。)

バージョン 2.6.11 以前の Linux カーネルでは、 flock() は NFS 上のファイルのロックを行わない (つまり、ロックの対象はローカルシステムに限定されていた)。 その代わり、十分に最近のバージョンの Linux とロックをサポートするサーバーであれば、 fcntl(2) のバイト範囲ロックを使うことができた。 fcntl(2) のバイト範囲ロックは NFS 上で動作する。 Linux 2.6.12 以降では、NFS クライアントは、 ファイル全体に対するバイト範囲ロックでエミュレートすることで、 flock() ロックをサポートしている。 これは、fcntl(2) と flock() ロックが NFS 上では互いに影響しあうことを意味する。 Linux 2.6.37 以降では、 flock() ロック (と fcntl(2) のバイト範囲ロック) をローカルシステムに対するものとして扱う互換性モードが、 カーネルでサポートされている。 nfs(5) の local_lock オプションの議論を参照。

flock() アドバイザリロックだけを適用する。したがって、ファイルに適切なアクセス権を 付与していれば、プロセスは flock() の使用に無視して、ファイルへの入出力を行うことができる。

flock() と fcntl(2) は fork されたプロセスと dup(2) で違った動作をする。 flock() を fcntl(2) を使って実装しているシステムでは、 flock() の動作はこのマニュアルページに記載されているものとは違うだろう。

ロックの変換 (共有ロックから排他ロックへ、もしくはその反対) がアトミックに 行われることは保証されていない: 既存のロックがまず削除され、それから新しい ロックが設定される。この 2つのステップの間に、他のプロセスからの処理待ちの ロック要求が認められるかもしれず、結果として変換は停止 (block) したり、 (LOCK_NB が指定された場合には) 失敗したりする。 (これは元々の BSD の動作であり、多くの他の実装でも起こる。)

関連項目
flock(1), close(2), dup(2), execve(2), fcntl(2), fork(2), open(2), lockf(3) Linux カーネルソース内の Documentation/filesystems/locks.txt (以前のカーネルでは Documentation/locks.txt)

この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。