1 環境
VMware Workstation 12 Player上のゲストマシンを使っています。
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
[root@server ~]# uname -r
3.10.0-514.el7.x86_64
2 コマンドオプション
[root@server flock]# flock --version
flock from util-linux 2.23.2
[root@server flock]# flock --help
Usage:
flock [options] <file|directory> <command> [command args]
flock [options] <file|directory> -c <command>
flock [options] <file descriptor number>
オプション:
-s --shared get a shared lock
-x --exclusive get an exclusive lock (default)
-u --unlock remove a lock
-n --nonblock fail rather than wait
-w --timeout <secs> wait for a limited amount of time
-E --conflict-exit-code <number> exit code after conflict or timeout
-o --close close file descriptor before running command
-c --command <command> run a single command string through the shell
-h, --help display this help and exit
-V, --version output version information and exit
For more details see flock(1).
3 排他ロックの使い方(-x)
事前にターミナルを2つオープンします。それぞれ、ターミナル1,ターミナル2と呼びます。
ターミナル1
ロックを作成する。
[root@server flock]# touch /tmp/lock
排他モードでファイル(aa)をオープンする。
[root@server flock]# flock -x /tmp/lock vi aa
12345
ターミナル2
排他モード(-x)でファイル(aa)をオープンする。しかし、catコマンドがブロックします。
[root@server flock]# flock -x /tmp/lock cat aa
Crtl +c 押下してコマンドを終了する。
[root@server flock]# flock -x /tmp/lock cat aa
^C
共有モード(-s)でファイル(aa)をオープンする。しかし、catコマンドがブロックします。
[root@server flock]# flock -s /tmp/lock cat aa
Crtl +c 押下してコマンドを終了する。
[root@server flock]# flock -s /tmp/lock cat aa
^C
4 共有ロックの使い方(-s)
事前にターミナルを2つオープンします。それぞれ、ターミナル1,ターミナル2と呼びます。
ターミナル1
ロックを作成する。
[root@server flock]# touch /tmp/lock
共有モード(-s)でファイル(aa)をオープンする。
[root@server flock]# flock -s /tmp/lock vi aa
12345
ターミナル2
共有モード(-s)でファイル(aa)をオープンする。catコマンドはブロックしません。
[root@server flock]# flock -s /tmp/lock cat aa
12345
排他モード(-x)でファイル(aa)をオープンする。catコマンドはブロックします。
[root@server flock]# flock -x /tmp/lock cat aa
5 まとめ
3章,4章のまとめです。
プロセスAが先にロックを獲得し、後から実行するプロセスBのロック可否を表しています。
〇
はロックが獲得できることを意味します。
✖
はロックが獲得できないことを意味します。
プロセスB | プロセスB | ||
---|---|---|---|
共有ロック(-s) | 排他ロック(-x) | ||
プロセスA | 共有ロック(-s) | ○ | × |
プロセスA | 排他ロック(-x) | × | × |
6 その他
flockコマンドが実行するシステムコールを確認してみました。
flockシステムコールを呼び出していることがわかります。
第2引数に、LOCK_SH,LOCK_EXを指定していることがわかります。
[root@server flock]# strace -e trace=open,flock flock -s /tmp/lock cat aa
open("/tmp/lock", O_RDONLY|O_CREAT|O_NOCTTY, 0666) = 3
flock(3, LOCK_SH) = 0
12345
[root@server flock]# strace -e trace=open,flock flock -x /tmp/lock cat aa
open("/tmp/lock", O_RDONLY|O_CREAT|O_NOCTTY, 0666) = 3
flock(3, LOCK_EX) = 0
12345
7 その他2
flockコマンドを使って、コマンドの実行をシリアライズしてみます。
TPの内容
[root@kvm ~]# cat tp.sh
#!/usr/bin/bash
NUM_MAX=10
i=0
while [ "$i" -lt ${NUM_MAX} ]
do
logger "$1 (PID=$$,NUM=$i)"
sleep 1
i=$((i+1))
done
ロックの作成
[root@kvm ~]# touch /tmp/lock
ログの確認
[root@kvm ~]# journalctl -f
プロセスAの起動
[root@kvm ~]# flock -x /tmp/lock ./tp.sh A
もう1つターミナルを開いて、TPを実行する。
プロセスBの起動
[root@kvm ~]# flock -x /tmp/lock ./tp.sh B
さらに、もう1つターミナルを開いて、TPを実行する。
プロセスCの起動
[root@kvm ~]# flock -x /tmp/lock ./tp.sh C
プロセスA,B,Cが順に実行されていることがわかります。
ログの確認
[root@kvm ~]# journalctl -f
11月 13 19:10:06 kvm root[20996]: A (PID=20995,NUM=0)
11月 13 19:10:07 kvm root[20999]: A (PID=20995,NUM=1)
11月 13 19:10:08 kvm root[21002]: A (PID=20995,NUM=2)
11月 13 19:10:09 kvm root[21004]: A (PID=20995,NUM=3)
11月 13 19:10:10 kvm root[21006]: A (PID=20995,NUM=4)
11月 13 19:10:11 kvm root[21008]: A (PID=20995,NUM=5)
11月 13 19:10:12 kvm root[21010]: A (PID=20995,NUM=6)
11月 13 19:10:13 kvm root[21012]: A (PID=20995,NUM=7)
11月 13 19:10:14 kvm root[21014]: A (PID=20995,NUM=8)
11月 13 19:10:15 kvm root[21016]: A (PID=20995,NUM=9)
11月 13 19:10:16 kvm root[21019]: B (PID=21018,NUM=0)
11月 13 19:10:17 kvm root[21021]: B (PID=21018,NUM=1)
11月 13 19:10:18 kvm root[21023]: B (PID=21018,NUM=2)
11月 13 19:10:19 kvm root[21025]: B (PID=21018,NUM=3)
11月 13 19:10:20 kvm root[21027]: B (PID=21018,NUM=4)
11月 13 19:10:21 kvm root[21029]: B (PID=21018,NUM=5)
11月 13 19:10:22 kvm root[21031]: B (PID=21018,NUM=6)
11月 13 19:10:23 kvm root[21033]: B (PID=21018,NUM=7)
11月 13 19:10:24 kvm root[21035]: B (PID=21018,NUM=8)
11月 13 19:10:25 kvm root[21037]: B (PID=21018,NUM=9)
11月 13 19:10:26 kvm root[21040]: C (PID=21039,NUM=0)
11月 13 19:10:27 kvm root[21051]: C (PID=21039,NUM=1)
11月 13 19:10:28 kvm root[21053]: C (PID=21039,NUM=2)
11月 13 19:10:29 kvm root[21055]: C (PID=21039,NUM=3)
11月 13 19:10:30 kvm root[21057]: C (PID=21039,NUM=4)
11月 13 19:10:31 kvm root[21059]: C (PID=21039,NUM=5)
11月 13 19:10:32 kvm root[21061]: C (PID=21039,NUM=6)
11月 13 19:10:33 kvm root[21063]: C (PID=21039,NUM=7)
11月 13 19:10:34 kvm root[21065]: C (PID=21039,NUM=8)
11月 13 19:10:35 kvm root[21067]: C (PID=21039,NUM=9)
コメント