shell命令flock通过加锁方式实现互斥访问。
常用语多进程间互斥访问。
flock用flock(2)系统调用实现。
用法
flock [-sxon] [-w timeout] lockfile [-c] command... flock [-sxon] [-w timeout] lockdir [-c] command... flock [-sxun] [-w timeout] fd
参数
-s: 获取共享锁,有时被称为只读锁。
-x,-e:获取互斥锁,有时称为写锁。默认。
-u:释放锁。这个不是必须的,当文件关闭时(进程结束后,进程文件都被关闭)锁被自动释放。但是,特殊情况下是必须的,例如受锁保护的命令行fork一个后台进程,此进程不应该持有锁。
Drop a lock. This is usually not required, since a lock is automatically dropped when the
file is closed. However, it may be required in special cases, for example if the enclosed
command group may have forked a background process which should not be holding the lock.
-n:非阻塞,获取锁失败后立刻返回,退出码1。
-w:seconds,等待超时。
-o:在执行命令前,关闭被锁文件的文件描述符。这是有用的,当时命令行fork一个子进程,该子进程不应该持有锁。
-c:传递一个单独command给shell(在shell中执行命令)。-c选项表示,如果成功锁定,则执行其后用双引号括起的命令,如果是多个命令,可以用分号分隔。
描述
该命令管理flock(2) locks为shell scripts或the command line。
第一或第二种形式在命令执行时回绕锁。它锁住指定文件或路径(若不存在创建它)。
第三种形式在脚本中应用方便,形式如下
( flock -n 9 || exit 1 # ... commands executed under lock ... ) 9>/var/lock/mylockfile
The mode used to open the file doesn‘t matter to flock; using > or >> allows the lockfile to be cre‐
ated if it does not already exist, however, write permission is required; using < requires that the
file already exists but only read permission is required.
默认情况下,flock会阻塞等,直到获取锁。
flock(2)中描述:Locks created by flock() are associated with an open file table entry. This means that duplicate
file descriptors (created by, for example, fork(2) or dup(2)) refer to the same lock, and this lock
may be modified or released using any of these descriptors. Furthermore, the lock is released
either by an explicit LOCK_UN operation on any of these duplicate descriptors, or when all such
descriptors have been closed.
应用
1 crontab运用flock防止重复执行
* * * * * (flock -xn ./test.lock -c "sh /root/test.sh") #-n 为非阻塞模式
2 机器down机自动启动或重启
可以在daemon开始的时候, 打开一个文件然后获取一个写锁. 守护脚本也打开文件并设置写锁, 然后阻塞, 一旦写锁获得成功, 则说明daemon已经挂了. 此时守护脚本重启daemon并放弃写锁.
flock -x ./test.lock -c "/usr/local/nginx/sbin/nginx" #去掉-n表示使用阻塞模式
运行中...
再次执行
flock -x ./test.lock -c "/usr/local/nginx/sbin/nginx" #去掉-n表示使用阻塞模式
阻塞中...
模拟down机
[[email protected] ~]# ps aux |grep "nginx"|grep"master"|grep -v "grep"|awk‘{print $2}‘|xargskill -9
kill后阻塞的命令马上执行 新的进程PID立马产生。