• [fcntl][NFS][MacOS] 锁文件 IOError: [Errno 35] Resource temporarily unavailable


    lockf 是 fcntl的封装,底层实现一样

    flock: lock the whole file,只能对整个文件上锁,支持建议锁,共享锁,排他锁, 不能用在nfs上
    fcntl(可用在nfs上), lockf: 整个文件 或者 文件部分字节的锁, 只支持排他锁
    共享锁必须是读打开,排他锁必须是写打开
    排他锁:写锁, 独占锁, 同一时间只有一个进程可以加

    fcntl.LOCK_SH    '共享锁'
    fcntl.LOCK_EX    '排他锁'
    fcntl.LOCK_NB    '非阻塞锁——如果指定此参数,函数不能获得文件锁就立即返回,否则,函数会等待获得文件锁。LOCK_NB可以同LOCK_SH或LOCK_NB进行按位或(|)运算操作。 fcntl.flock (f,fcntl.LOCK_EX|fcntl.LOCK_NB)'
    fcntl.LOCK_UN    '解锁'
    

    环境:
    client: macos
    protocol: nfsv4

    目的:
    强制锁定文件以做写操作

    实现方式:
    fcntl.lockf(f, fcntl.LOCK_SH | fcntl.LOCK_NB)

    验证是否锁成功:
    1.在terminal 1中:

    import fcntl
    path = '/var/root/dev/1.txt'
    f = open(path, 'wb')
    fcntl.lockf(f, fcntl.LOCK_SH)
    print('getpid:{0}'.format(os.getpid()))
    
    1. 保持以上terminal 不中断,开第二个terminal,运行同样代码,执行到lockf时,无任何输出

    2. 重新来,在lockf那一段加入一个参数 fcntl.LOCK_NB

    fcntl.lockf(f, fcntl.LOCK_SH | fcntl.LOCK_NB)

    1. 重新执行step1 和 step2, 到第二个fcntl.lockf时,得到如下error messgae,说明锁成功:
    >>> f = open(path, 'wb')
    >>> fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IOError: [Errno 35] Resource temporarily unavailable
    >>> fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IOError: [Errno 35] Resource temporarily unavailable
    
    1. 所以,一般写操作,需要锁定文件,用try/except 来捕获IOError:
      把以上代码补完整:
    import fcntl
    path = '/var/root/dev/1.txt'
    try:
        with open(path, 'wb') as f:
            fcntl.lockf(f, fcntl.LOCK_SH)
            print('getpid:{0}'.format(os.getpid()))
    except IOError as e:
        print("Another instance is already running {0}".format(e))
         
    
    1. 解锁用:fcntl.LOCK_UN , f.close()也能解锁。

    另外学到个新用法 os.fstat(f.fileno()) 可以输出文件的uid,gid,device等信息;

    (Pdb) os.fstat(fildes.fileno())
    posix.stat_result(st_mode=33216, st_ino=4297196284, st_dev=872415337, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1587695736, st_mtime=1587695736, st_ctime=1587695736)
    

    此段代码在smb mount point上执行,报错如下,应该是lockf不支持smb,但是还能不能继续用fcntl了呢?
    IOError: (45, 'Operation not supported')

    补充:

    enum nfs_lock_type4 {
               READ_LT         = 1,
               WRITE_LT        = 2,
               READW_LT        = 3,    /* blocking read */
               WRITEW_LT       = 4     /* blocking write */
       };
    

    nfs.opcode == 12 ----> create lock
    nfs.opcode == 14 ----> unlock file

  • 相关阅读:
    [bug] C:warning: implicit declaration of function ‘getline’
    [Java] 内部类
    [架构] 数据库技术选型
    [bug] Maven修改pom文件后jdk版本回退
    [物联网] 电气 & 工控
    [bug] mysql 忘记密码
    [物联网] 电路分析
    机器学习sklearn(二十五): 模型评估(五)量化预测的质量(二)分类指标
    机器学习sklearn(二十四): 模型评估(四)量化预测的质量(一)scoring 参数: 定义模型评估规则
    机器学习sklearn(二十三): 模型评估(三)交叉验证:评估估算器的表现(三) 交叉验证迭代器
  • 原文地址:https://www.cnblogs.com/vivivi/p/12765452.html
Copyright © 2020-2023  润新知