我今天看到一种写法,创建了一个文件当做锁。这种写法相比管道,信号有什么优缺点呢?为啥我们自己写,包括面试官面试从没有遇到过这种答案啊~谢谢各位大佬了~~~
1
lithiumii 2019-09-04 15:04:04 +08:00 via Android
flock ?挺常见的吧
|
2
lihongjie0209 2019-09-04 15:11:13 +08:00
简单啊,要什么自行车
|
3
zarte 2019-09-04 15:25:07 +08:00
不是每种语言都有管道信号这东东
|
4
tabris17 2019-09-04 15:36:46 +08:00
flock 的性能比 posix 信号量差一个数量级,但是也不算很糟糕,够用。而且大多数语言都有实现 flcok
|
6
momocraft 2019-09-04 15:54:02 +08:00 1
你说的是 pid file 吗?
|
7
Mirana 2019-09-04 17:03:43 +08:00
信号能实现多进程间的互斥吗。。
|
8
ipwx 2019-09-04 17:25:13 +08:00 via Android
nfs 支持文件锁,虽然不知道一致性有多好。这可是通用版低配版的 zookeeper 啊
|
9
foreverfuck 2019-09-04 17:54:32 +08:00
文件锁不错,单机可以,多台服务器的话,如果通过文件共享来锁的话,就尴尬了。还有一点,就是死锁卡住就操蛋
|
10
blueberryman OP @lithiumii 不是 flock,它只是当做 mutex 用。如果想执行类似于访问可重入资源的问题就会看这个文件是否存在来判断下一步的操作
|
11
blueberryman OP @lihongjie0209 我也觉得挺简单的,open 一下就完了,但是这种方法有啥缺点呢?而且优点只是简单吗?
|
12
blueberryman OP @momocraft 对对对,那个宏就叫这个名字,我都不知道怎么百度,这东西可以被管道,fifo 什么的替代吗?或者说有这个了我还需要管道吗
|
13
wd 2019-09-04 20:46:53 +08:00 via iPhone
不同程序间配合可以用这个吧,比较简单。比如 shell 程序间想并行又有依赖的时候可以通过这个实现
|
14
blueberryman OP @zarte 我们用的是 c,上来建了一个这个文件,说是为了防止 telnet 登录,我就想了,管道也是文件啊,那我干嘛还要用管道啊,废弃它吧
|
15
blueberryman OP @tabris17 好像不是 flock,文件的内容不重要,只关心文件是否存在,如果存在就不允许 telnet
|
16
blueberryman OP @Mirana 信号好像可以吧,我这个最终是标记允不允许 telnet
|
17
blueberryman OP @wd 有依赖?你的意思是互斥资源吗?
|
18
blueberryman OP @foreverfuck 好像不是文件锁,文件内容不重要,只关心文件是否存在
|
19
FrankHB 2019-09-04 20:55:40 +08:00 1
看起来不是 flock,是 /var/lib/pacman/db.lck 之类的吧……实现容易,可移植性(跨操作系统、体系结构和语言)好,外部可见可查询状态允许多实例共享,程序中途挂掉状态维护失败留下烂摊子时在用户界面就能干掉,必要时可以方便附加元数据(文件属性和内容)。
管道和 FIFO 之类比普通文件可移植性差。至少 Windows 上就那么容易用。 |
20
FrankHB 2019-09-04 20:56:28 +08:00
就那么容易用→就没那么容易用……
|
21
tabris17 2019-09-04 20:57:34 +08:00
@blueberryman 那就是用来当作开关配置了,偷懒罢了
|
22
wd 2019-09-04 21:18:36 +08:00 via iPhone
@blueberryman #17 不是互斥 比如程序 1 中间会产出一些数据 程序 2 运行到一定程度会需要 那这两个程序要么串行运行 肯定能保证程序 2 依赖的数据都有 要么通过这样的文件来通知程序 2 数据好了
|
23
zjqzxc 2019-09-04 21:32:26 +08:00
如果见过有人拿文件做 RPC 的话,就淡定了
|
24
momocraft 2019-09-04 22:30:43 +08:00
pid file 僅僅提供 (基於君子協定的) 互斥, 以及聲明創建者的 pid (如果使用者正確地把 pid 寫入文件).
功能顯然不能和管道信號量比較, 更多是個習慣用法. 但是簡單可移植. |
25
feather12315 2019-09-04 22:37:40 +08:00 via Android 1
|
26
blueberryman OP @momocraft 那管道也是个文件,移植效果会差很多吗?
|
27
blueberryman OP @FrankHB 多谢大佬,不过我们关心的只是是否有这个文件,linux 下管道也是个文件,这个文件是 open 创建的还是管道创建的有影响吗?我的意思是管道的移植性会很差吗?
|
28
swulling 2019-09-04 23:43:42 +08:00 via iPhone
file lock 对多进程生效呗,单机其他的方法都挺麻烦的
|
29
codeyung 2019-09-04 23:44:56 +08:00
文件锁 单机 比如你定时多进程跑相同的东西 加个判断上锁了别的进程就自己关闭 保证进程的顺序执行
|
30
momocraft 2019-09-04 23:51:18 +08:00
> #27
不知道, 我沒有像你說的那樣用過管道文件, 不知道你這樣做是否正確. "簡單可移植" 的意思是說 pid file 這個做法僅需要相當於 open + O_CREAT + O_EXCL 的 api. 我甚至不知道其他 os 有沒有管道. |
31
dusu 2019-09-04 23:54:08 +08:00 via iPhone
flock 真的能用做锁?我试过网上 n 多 flock 当锁的示例代码,多进程跑的时候几乎没一个能用的。当然,也有可能我用法和理解有误,也建议楼主深度测试下;
如果能用的话,除了没法分布式的致命弱点外,小项目还是可以考虑一下的。 P.S. 早上 redis 早真香 |
32
jinliming2 2019-09-05 00:37:53 +08:00 via iPhone
flock 就是不关心文件内容的吧?只要一个空文件然后独占打开就行了。
pid file 是用来跟踪进程 ID 的吧,貌似跟锁没太大关系,可能用于防止多开。 |
33
dangyuluo 2019-09-05 01:04:37 +08:00
flock 这个东西只能当作简单的锁,比如禁止两次 nightly 备份同时进行。真要做多线程锁的话,flock 缺乏`test_and_set`这个重要的原子操作。
|
34
blueberryman OP @dusu 好哒,lz 这两天双系统一直丢引导,过几天好了就测~
|
35
maxbon 2019-09-07 16:35:38 +08:00
我知道楼主说的写法是什么样子的,下面这种对吧,
```shell [ -f /tmp/lock.file ] && exit echo $$ > /tmp/lock.file sleep 1 [ "x$(cat /tmp/lock.file)" == "x"$$ ] || exit echo OK rm -f /tmp/lock.file ``` |
36
FrankHB 2019-09-08 22:59:39 +08:00
@blueberryman 可移植性是相对而言,POSIX 环境你要折腾基本上不用考虑区别,但没 POSIX 原生支持就可能有问题。像 Windows 下没直接对应管道文件的东西,Windows 的管道不共享 Win32 文件系统命名空间(一般应用没事也不会折腾 NT 命名空间),自然可移植性就差。
如果是普通的文件,直接标准 C 的 API 可能都够用——创建文件有 C11 的 'x' mode 支持下 fopen 都够了。虽然 stdio 的缓冲是多余的,但考虑应用都能容忍 shell 的性能的场景这个不是什么大问题——只不过实际情况是,就 Windows 对 C 的支持,还不如直接 open 了。当然,微软默认还不想让你用 open (没 deprecated 的是 _open ),这个另说。 实际的主要问题是,既然说白了只是想要在 VFS 里有个占位符,没需求非得用特殊文件,干嘛那么麻烦特意用管道文件? |