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('文件加鎖,沒法執行,請稍後運行。\n',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.htmlhtml

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

lockf 子進程不會繼承主進程的鎖linux

flock 子進程繼承主進程的鎖,這個感受用的多些ide

1. flock 在linux下 函數原型

#include 函數

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

    其中fd是系統調用open返回的文件描述符,operation的選項有:spa

LOCK_SH :共享鎖.net

LOCK_EX :排他鎖或者獨佔鎖unix

LOCK_UN : 解鎖。code

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('文件已加鎖,沒法執行,請稍後運行。\n',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 相互無影響
'''
相關文章
相關標籤/搜索