首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
宝塔
V2EX  ›  程序员

有没有大神了解 Linux 中创建文件当做锁有什么特点

  •  
  •   blueberryman · 74 天前 via Android · 2208 次点击
    这是一个创建于 74 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我今天看到一种写法,创建了一个文件当做锁。这种写法相比管道,信号有什么优缺点呢?为啥我们自己写,包括面试官面试从没有遇到过这种答案啊~谢谢各位大佬了~~~

    36 回复  |  直到 2019-09-08 22:59:39 +08:00
        1
    lithiumii   74 天前 via Android
    flock ?挺常见的吧
        2
    lihongjie0209   74 天前
    简单啊,要什么自行车
        3
    zarte   74 天前
    不是每种语言都有管道信号这东东
        4
    tabris17   74 天前
    flock 的性能比 posix 信号量差一个数量级,但是也不算很糟糕,够用。而且大多数语言都有实现 flcok
        5
    reus   74 天前
    flock 是系统调用,很常见的东西


    @zarte 这些都有操作系统提供的实现,大部分语言都能用
        6
    momocraft   74 天前   ♥ 1
    你说的是 pid file 吗?
        7
    Mirana   74 天前
    信号能实现多进程间的互斥吗。。
        8
    ipwx   74 天前 via Android
    nfs 支持文件锁,虽然不知道一致性有多好。这可是通用版低配版的 zookeeper 啊
        9
    foreverfuck   74 天前
    文件锁不错,单机可以,多台服务器的话,如果通过文件共享来锁的话,就尴尬了。还有一点,就是死锁卡住就操蛋
        10
    blueberryman   74 天前 via Android
    @lithiumii 不是 flock,它只是当做 mutex 用。如果想执行类似于访问可重入资源的问题就会看这个文件是否存在来判断下一步的操作
        11
    blueberryman   74 天前 via Android
    @lihongjie0209 我也觉得挺简单的,open 一下就完了,但是这种方法有啥缺点呢?而且优点只是简单吗?
        12
    blueberryman   74 天前 via Android
    @momocraft 对对对,那个宏就叫这个名字,我都不知道怎么百度,这东西可以被管道,fifo 什么的替代吗?或者说有这个了我还需要管道吗
        13
    wd   74 天前 via iPhone
    不同程序间配合可以用这个吧,比较简单。比如 shell 程序间想并行又有依赖的时候可以通过这个实现
        14
    blueberryman   74 天前 via Android
    @zarte 我们用的是 c,上来建了一个这个文件,说是为了防止 telnet 登录,我就想了,管道也是文件啊,那我干嘛还要用管道啊,废弃它吧
        15
    blueberryman   74 天前 via Android
    @tabris17 好像不是 flock,文件的内容不重要,只关心文件是否存在,如果存在就不允许 telnet
        16
    blueberryman   74 天前 via Android
    @Mirana 信号好像可以吧,我这个最终是标记允不允许 telnet
        17
    blueberryman   74 天前 via Android
    @wd 有依赖?你的意思是互斥资源吗?
        18
    blueberryman   74 天前 via Android
    @foreverfuck 好像不是文件锁,文件内容不重要,只关心文件是否存在
        19
    FrankHB   74 天前   ♥ 1
    看起来不是 flock,是 /var/lib/pacman/db.lck 之类的吧……实现容易,可移植性(跨操作系统、体系结构和语言)好,外部可见可查询状态允许多实例共享,程序中途挂掉状态维护失败留下烂摊子时在用户界面就能干掉,必要时可以方便附加元数据(文件属性和内容)。
    管道和 FIFO 之类比普通文件可移植性差。至少 Windows 上就那么容易用。
        20
    FrankHB   74 天前
    就那么容易用→就没那么容易用……
        21
    tabris17   74 天前
    @blueberryman 那就是用来当作开关配置了,偷懒罢了
        22
    wd   74 天前 via iPhone
    @blueberryman #17 不是互斥 比如程序 1 中间会产出一些数据 程序 2 运行到一定程度会需要 那这两个程序要么串行运行 肯定能保证程序 2 依赖的数据都有 要么通过这样的文件来通知程序 2 数据好了
        23
    zjqzxc   74 天前
    如果见过有人拿文件做 RPC 的话,就淡定了
        24
    momocraft   74 天前
    pid file 僅僅提供 (基於君子協定的) 互斥, 以及聲明創建者的 pid (如果使用者正確地把 pid 寫入文件).

    功能顯然不能和管道信號量比較, 更多是個習慣用法. 但是簡單可移植.
        25
    feather12315   74 天前 via Android   ♥ 1
        26
    blueberryman   74 天前 via Android
    @momocraft 那管道也是个文件,移植效果会差很多吗?
        27
    blueberryman   74 天前 via Android
    @FrankHB 多谢大佬,不过我们关心的只是是否有这个文件,linux 下管道也是个文件,这个文件是 open 创建的还是管道创建的有影响吗?我的意思是管道的移植性会很差吗?
        28
    swulling   74 天前 via iPhone
    file lock 对多进程生效呗,单机其他的方法都挺麻烦的
        29
    codeyung   74 天前
    文件锁 单机 比如你定时多进程跑相同的东西 加个判断上锁了别的进程就自己关闭 保证进程的顺序执行
        30
    momocraft   74 天前
    > #27
    不知道, 我沒有像你說的那樣用過管道文件, 不知道你這樣做是否正確.
    "簡單可移植" 的意思是說 pid file 這個做法僅需要相當於 open + O_CREAT + O_EXCL 的 api. 我甚至不知道其他 os 有沒有管道.
        31
    dusu   74 天前 via iPhone
    flock 真的能用做锁?我试过网上 n 多 flock 当锁的示例代码,多进程跑的时候几乎没一个能用的。当然,也有可能我用法和理解有误,也建议楼主深度测试下;

    如果能用的话,除了没法分布式的致命弱点外,小项目还是可以考虑一下的。

    P.S. 早上 redis 早真香
        32
    jinliming2   74 天前 via iPhone
    flock 就是不关心文件内容的吧?只要一个空文件然后独占打开就行了。
    pid file 是用来跟踪进程 ID 的吧,貌似跟锁没太大关系,可能用于防止多开。
        33
    dangyuluo   74 天前
    flock 这个东西只能当作简单的锁,比如禁止两次 nightly 备份同时进行。真要做多线程锁的话,flock 缺乏`test_and_set`这个重要的原子操作。
        34
    blueberryman   73 天前 via Android
    @dusu 好哒,lz 这两天双系统一直丢引导,过几天好了就测~
        35
    maxbon   71 天前
    我知道楼主说的写法是什么样子的,下面这种对吧,
    ```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   70 天前
    @blueberryman 可移植性是相对而言,POSIX 环境你要折腾基本上不用考虑区别,但没 POSIX 原生支持就可能有问题。像 Windows 下没直接对应管道文件的东西,Windows 的管道不共享 Win32 文件系统命名空间(一般应用没事也不会折腾 NT 命名空间),自然可移植性就差。
    如果是普通的文件,直接标准 C 的 API 可能都够用——创建文件有 C11 的 'x' mode 支持下 fopen 都够了。虽然 stdio 的缓冲是多余的,但考虑应用都能容忍 shell 的性能的场景这个不是什么大问题——只不过实际情况是,就 Windows 对 C 的支持,还不如直接 open 了。当然,微软默认还不想让你用 open (没 deprecated 的是 _open ),这个另说。
    实际的主要问题是,既然说白了只是想要在 VFS 里有个占位符,没需求非得用特殊文件,干嘛那么麻烦特意用管道文件?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   744 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 29ms · UTC 21:04 · PVG 05:04 · LAX 13:04 · JFK 16:04
    ♥ Do have faith in what you're doing.