flock in shell
来源:互联网 发布:做淘宝要先学美工吗 编辑:程序博客网 时间:2024/05/22 07:00
当多个进程可能会对同样的数据执行操作时,这些进程需要保证其它进程没有也在操作,以免损坏数据。
通常,这样的进程会使用一个「锁文件」,也就是建立一个文件来告诉别的进程自己在运行,如果检测到那个文件存在则认为有操作同样数据的进程在工作。这样的问题是,进程不小心意外死亡了,没有清理掉那个锁文件,那么只能由用户手动来清理了。像 pacman 或者 apt-get 一些数据库服务经常在意外关闭时留下锁文件需要用户清理。我以前写了个pidfile,它会将自己的 pid 写到文件里去,所以,如果启动时文件存在,但是对应的进程不存在,那么它也可以知道没有其它进程要访问它要访问的数据(这里只讨论如何避免数据的并发讨论,不考虑进程意外退出时的数据完整性)。但是,Linux 的 pid 是会复用的。而且,检查 pidfile 也有点麻烦不是么?(还有竞态呢)
某天,我发现了 flock 这个系统调用。flock 是对于整个文件的建议性锁。也就是说,如果一个进程在一个文件(inode)上放了锁,那么其它进程是可以知道的。(建议性锁不强求进程遵守。)最棒的一点是,它的第一个参数是文件描述符,在此文件描述符关闭时,锁会自动释放。而当进程终止时,所有的文件描述符均会被关闭。于是,很多时候就不用考虑解锁的事情啦。
flock 有个对应的 shell 命令也叫 flock,很好用的。使用最广泛的 cronie 这个定时任务服务很笨的,不像小巧的 dcron 那样同一任务不会同时跑多个。于是乎,服务器上经常看到一堆未退出的 cron 任务进程。把所有这样的任务包一层 flock 就不会导致 cronie 启动 N 个进程做同一件事啦:
flock -n /tmp/.my.lock -c 'command to run'
即使是 dcron,有时会有两个操作同一数据的任务,也需要使用 flock 来调度。不过这次不用-n
参数让文件被锁住时失败退出了。我们要等拥有锁的进程完事再执行。如下,两个任务(有所修改),一个是从远程同步数据到本地的,另一个是备份同步过来的数据的。同时执行的话,就会备份到不完整的数据了。
*/7 * * * * ID=syncdata LANG=zh_CN.UTF-8 flock /tmp/.backingup -c my_backup_script@daily ID=backupdata LANG=zh_CN.UTF-8 [ -d ~/data ] && cd ~/data && nice -n19 ionice -c3 flock /tmp/.backingup -c "tar cJf backup_$(date +"%Y%m%d").tar.xz data_dir --exclude='*~'"
flock 命令除了接收文件名参数外,还可以接收文件描述符参数。这种方法在 shell 脚本里特别有用。比如如下代码:
lockit () { exec 7<>.lock flock -n 7 || { echo "Waiting for lock to release..." flock 7 }}
exec
行打开.lock
文件为 7 号文件描述符,然后拿 flock 尝试锁它。如果失败了,就输出一条消息,并且等待锁被释放。那个 7 号文件描述符就让它一直开着了,反正脚本执行完毕内核会释放,也不用去调用trap
内建命令了。
上边有一点很有意思的是,flock 是一个子进程,但是因为文件描述符在 fork 和 execve 中会共享,而 flock 锁在 fork 和 execve 时也不会改变,所以子进程在那个文件描述符上加锁后,即使它退出了,因为那个文件描述符父进程还有一份,所以不会被关闭,锁也就得以保留。(所以,如果余下的脚本里要是有进程带着那个文件描述符 fork 到后台锁就不会在脚本执行完后自动解除啦……)
PS: 经我测试,其它一些类 Unix 系统上或者没有 flock 这个系统调用,只有 fcntl 那个,或者行为和 Linux 的不一样。
- flock in shell
- against parallel execution in shell (flock)
- Shell锁-flock
- Linux Shell的锁:flock
- flock shell script 使用速记
- flock
- flock
- flock
- flock
- flock
- linux之flock实现shell锁
- linux shell flock文件锁用法,以及文件按行队列处理
- Flock 测试
- Flock操作
- flock简介
- linux flock
- flock()函数
- bash flock
- 关于windows下JAVA环境变量的配置
- 【问题解决】Project facet Java version 1.7 is not supported.
- [Android实例] 最全的Android开发资源整理--进阶必备
- 匿名内部类
- 日语学习之沪江N4基础 20141125
- flock in shell
- 形参与实参的区别
- Android中如何将dp,dip,sp与px相互转化
- 应用程序无法启动,因为应用程序的并行配置不正确解决方案一览
- java设计模式之工厂模式
- 一些学习资源(转)
- 使用国际开源项目构建一个完整的GIS(地理信息)应用系统
- MySQL执行计划
- WPS下EndNote文献管理软件的使用