zoukankan      html  css  js  c++  java
  • fcntl 加锁模块


    #
    !/usr/bin/python # coding:utf8 import os import sys import time import fcntl # 导入模块 class FLOCK(object): def __init__(self, name): """ :param name: 文件名 """ self.fobj = open(name, 'w') self.fd = self.fobj.fileno() def lock(self): try: fcntl.lockf(self.fd, fcntl.LOCK_EX | fcntl. LOCK_NB) # LOCK_NB: 使用了fcntl.LOCK_NB,已有进程对该文件已加锁,本进程得不到锁时直接退出,不阻塞。如果不加非阻塞参数,得不到锁就卡在这里一直傻等着直到拿到锁 print('给文件加锁,稍等 ... ...') time.sleep(20) return True except Exception as e : print('文件加锁,无法执行,请稍后运行。 ',e) return False def unlock(self): self.fobj.close() print('已解锁') if __name__ == "__main__": locker = FLOCK(sys.argv[1]) a = locker.lock() if a: print('文件已加锁') else: print('无法执行,程序已锁定,请稍等')

    fcntl.flock 和fcntl.lockf 的区别:http://blog.chinaunix.net/uid-28541347-id-5678998.html

    https://blog.csdn.net/mydriverc2/article/details/80263930

    lockf 子进程不会继承主进程的锁

    flock 子进程继承主进程的锁,这个感觉用的多些

    1. flock 在linux下 函数原型

    #include 

    int flock(int fd, int operation);  // Apply or remove an advisory lock on the open file specified by fd,只是建议性锁

        其中fd是系统调用open返回的文件描述符,operation的选项有:

    LOCK_SH :共享锁

    LOCK_EX :排他锁或者独占锁

    LOCK_UN : 解锁。

    LOCK_NB:非阻塞(与以上三种操作一起使用)

        关于flock函数,首先要知道flock函数只能对整个文件上锁,而不能对文件的某一部分上锁,这是于fcntl/lockf的第一个重要区别,后者可以对文件的某个区域上锁。其次,flock只能产生劝告性锁。我们知道,linux存在强制锁(mandatory lock)和劝告锁(advisory lock)。所谓强制锁,比较好理解,就是你家大门上的那把锁,最要命的是只有一把钥匙,只有一个进程可以操作。所谓劝告锁,本质是一种协议,你访问文件前,先检查锁,这时候锁才其作用,如果你不那么kind,不管三七二十一,就要读写,那么劝告锁没有任何的作用。而遵守协议,读写前先检查锁的那些进程,叫做合作进程。再次,flock和fcntl/lockf的区别主要在fork和dup。

        (1) flock创建的锁是和文件打开表项(struct file)相关联的,而不是fd。这就意味着复制文件fd(通过fork或者dup)后,那么通过这两个fd都可以操作这把锁(例如通过一个fd加锁,通过另一个fd可以释放锁),也就是说子进程继承父进程的锁。但是上锁过程中关闭其中一个fd,锁并不会释放(因为file结构并没有释放),只有关闭所有复制出的fd,锁才会释放。

    #!/usr/bin/env python
    # -*- coding:utf8 -*-
    
    import os
    import sys
    import time
    import fcntl  # 导入模块
    
    class FLOCK(object):
        def __init__(self, name):
            """ 
            :param name: 文件名
            """
            self.fobj = open(name, 'w')
            self.fd = self.fobj.fileno()
    
        def lock(self):
            try:
                fcntl.flock(self.fd, fcntl.LOCK_EX |fcntl.LOCK_NB )  # LOCK_NB: 使用了fcntl.LOCK_NB,已有进程对该文件已加锁,本进程得不到锁时直接退出,不阻塞如果不加非阻塞参数,得不到锁就卡在这里>
    一直等拿到锁            print('已给文件加锁, ... ...')
                fork_resu = os.fork()
                if fork_resu == 0:
                    print('子进程睡眠中')
                    time.sleep(20)
                    print('子进程退出')
                else:
                    sys.exit('主进程已退出')
                time.sleep(20)
                #return True
            except Exception as e : 
                print('文件已加锁,无法执行,请稍后运行。
    ',e)
                return False
                return False
    
    
        def unlock(self):
            self.fobj.close()
            print('已解锁')
    
    
    if __name__ == "__main__":
        locker = FLOCK(sys.argv[1])
        locker.lock()
    flock 子进程继承锁代码
    ''' 窗口1先运行
    [root@vm192-168-3-2 fcn_study]# python locktest.py  l.txt
    已给文件加锁, ... ...
    主进程已退出
    子进程睡眠中
    (base) [root@vm192-168-3-2 fcn_study]# 
    '''
    '''窗口2后运行
    [root@vm192-168-3-2 fcn_study]# python locktest.py  l.txt
    文件已加锁,无法执行,请稍后运行。
     [Errno 11] Resource temporarily unavailable
    
    '''

    如果代码改为lockf 加锁

    '''窗口1
    python locktest.py  l.txt
    已给文件加锁, ... ...
    主进程已退出
    (base) [root@vm192-168-3-2 fcn_study]# 子进程睡眠中
    
    '''
    '''窗口2
    root@vm192-168-3-2 fcn_study]# python locktest.py  l.txt
    已给文件加锁, ... ...
    主进程已退出
    (base) [root@vm192-168-3-2 fcn_study]# 子进程睡眠中
    
    
    
    ----窗口1和2 相互无影响
    '''
  • 相关阅读:
    node.js 安装后怎么打开 node.js 命令框
    thinkPHP5 where多条件查询
    网站title中的图标
    第一次写博客
    Solution to copy paste not working in Remote Desktop
    The operation could not be completed. (Microsoft.Dynamics.BusinessConnectorNet)
    The package failed to load due to error 0xC0011008
    VS2013常用快捷键
    微软Dynamics AX的三层架构
    怎样在TFS(Team Foundation Server)中链接团队项目
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/11767787.html
Copyright © 2011-2022 走看看