Skip to content

Latest commit

 

History

History
209 lines (145 loc) · 5.28 KB

425-191368-[专业选修]文件锁.sy.md

File metadata and controls

209 lines (145 loc) · 5.28 KB
show version enable_checker
step
1.0
true

文件锁

回忆

  • python 拷贝程序运行比较顺利
  • 但是两个进程同时写的同一个文件可能有问题
  • 比如两个一起写
  • 后面就会覆盖前面
  • 怎么办呢?🤔

搜锁

图片描述

查看

图片描述

导入

  • import fcntl
  • help(fcntl)

图片描述

  • 这个 module 的意思看起来是
  • file control

尝试

  • 新开一个游乐园
    • import fcntl
    • f = open("oeasy.txt","wb")
    • fcntl.lockf(f,fcntl.LOCK_EX)
  • 再开一个有游乐园
    • import fcntl
    • f = open("oeasy.txt","wb")
    • fcntl.lockf(f,fcntl.LOCK_EX)
  • 第二个在阻塞等待的过程中
  • 只要第一个不开锁
  • 第二个就啥都干不了

图片描述

解锁

图片描述

  • 第一个解锁了
  • 第二个就排上队了
  • 然后他就把文件给锁上了
  • 第一个想要再写
  • 就进入了阻塞等待的队列中

图片描述

  • 系统怎么知道到底锁的是哪个文件呢?

确认文件

  • open 之后的得到的 f 有个一属性
  • 可以确认唯一的 file

图片描述

锁的类型

  • 我想试试其他类型的锁
  • 可以么?

图片描述

  • 看起来像是 c 语言中枚举类型的值
  • 用 lockf 不可以
  • 找到一个 flock
  • 就可以用了

分享锁

  • 一个 terminal 用了 fcntl.LOCK_SH 分享锁
  • 另一个想上独享锁 fcntl.LOCK_EX 不行

图片描述

  • 但是要上分享锁就可以

图片描述

  • 我们再试试 NB 锁
  • 两个 terminal 太麻烦

tmux

  • 在终端里面运行 tmux 开启
  • 左右分开
    • ctrl+b然后%
  • 左右切换
    • ctrl+b然后
    • ctrl+b然后
  • 然后左右分别跑游乐场

图片描述

独享

  • 右边先拿到一个独享锁 fcntl.LOCK_EX
  • 左边再尝试得到一个分享锁 fcntl.LOCK_SH
  • 果然被阻塞了

图片描述

  • 我们可以用具体的值来进行解锁么?

具体数值

图片描述

图片描述

  • 解锁之后左边立刻阻塞结束
  • 得到了分享锁
  • 但是我不想要阻塞可以么?

阻塞

  • 先查帮助手册

图片描述

  • 如果 分享锁 LOCK_SH 和 阻塞标志 LOCK_NB 进行 bitwise or (按位进行的或运算)
  • 或者 独享锁 LOCK_EX 和 阻塞标志 LOCK_NB 进行 bitwise or
  • 那么这个如果这个锁不能得到
  • 就不阻塞了
  • 直接报 OSError
  • 扔出一个异常
  • 错误号属性被设置为 EACCS 或者 EAGAIN
  • 动手试试

按位或

图片描述

  • 这些数字刚好是某个二进制位
  • 彼此之间不会影响
  • 8 位构成一个状态字字节

状态字细节

图片描述

非阻塞独享

图片描述

  • 2 | 4 是按位或运算
  • 得到的状态字是 6

图片描述

NB

图片描述

  • 左边先申请一个独享锁
  • 右边要申请,模式除了独享还包括 NB
  • NB 的意思就是 No Block 没有阻塞
  • 申请不到
  • 也不阻塞
  • 直接得到
    • Errno 11
    • BlockingIOError 阻塞 io 错误
    • 这是根据当前系统来的
  • 这读写到底怎么弄的?

###分析

图片描述

总结

  • 这次我们搞的是文件读写的锁定
  • 靠的是 fcntl 这个包
  • 可以有
    • 分享锁 LOCK_SH
    • 独享锁 LOCK_EX
    • 阻塞标志 LOCK_NB
    • 取消锁 LOCK_UN
  • 不过得到锁了之后
  • 也是在原始基础上把原来的内容抹掉了
  • 我想要原来的都在
  • 新来的追加进去
  • 可以么?🤔
  • 下次再说 👋