#!/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.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('文件已加锁,无法执行,请稍后运行。\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 相互无影响
'''

fcntl 加锁模块的更多相关文章

  1. python 中给文件加锁——fcntl模块

    如果没有fcntl模块则用 sudo pip install fcntl安装 模块简单说明: 打开文件,不存在则创建之 f = open('./test','w') fcntl.flock(f,fcn ...

  2. 文件锁fcntl

    一.python中的文件锁 我们在写python应用的时候,当涉及到多个进程向同一个文件write(或者read)的情况,如果几个进程同时都对这个文件进行写操作,那么文件的内容就会变得非常混乱,这个时 ...

  3. Linux文件锁学习-flock, lockf, fcntl

    参考  linux中fcntl().lockf.flock的区别 这三个函数的作用都是给文件加锁,那它们有什么区别呢? 首先flock和fcntl是系统调用,而lockf是库函数.lockf实际上是f ...

  4. 文件锁-fcntl flock lockf

    这三个函数的作用都是给文件加锁,那它们有什么区别呢? 首先flock和fcntl是系统调用,而lockf是库函数.lockf实际上是fcntl的封装,所以lockf和fcntl的底层实现是一样的,对文 ...

  5. python-文件锁

    文件锁(fcntl) fcntl这个模块是Python自带的,但Windows没有,可以手工下载fcntl.py文件,然后保存到python的Lib目录下 锁类型(fcntl.flock函数的第二个参 ...

  6. 非阻塞io与记录锁

    非阻塞io 1.对比 阻塞io的例子:scanf从终端获取输入时,如果不输入程序就会一直停在那; 对一个已经有写锁的文件请求读时, 会一直空等直到前面的进程释放锁... 非阻塞的例子:读取文件内容, ...

  7. 遵循PEP8风格

    遵循PEP8风格 在编写python代码的时候我们应该采用统一的风格来编写代码,可以使代码更加容易读懂.采用和其他程序员统一的编码风格来写代码,也可以使项目更利于多人协作开发.即便代码只有你自己能看懂 ...

  8. 捉虫日记 | MySQL 5.7.20 try_acquire_lock_impl 异常导致mysql crash

    背景 近期线上MySQL 5.7.20集群不定期(多则三周,短则一两天)出现主库mysql crash.触发主从切换问题,堆栈信息如下: 从堆栈信息可以明显看出,在调用 try_acquire_loc ...

  9. python中给程序加锁之fcntl模块的使用

    python 中给文件加锁——fcntl模块import fcntl 打开一个文件##当前目录下test文件要先存在,如果不存在会报错.或者以写的方式打开f = open('./test')对该文件加 ...

随机推荐

  1. Go语言核心36讲(Go语言实战与应用十四)--学习笔记

    36 | unicode与字符编码 在开始今天的内容之前,我先来做一个简单的总结. Go 语言经典知识总结 在数据类型方面有: 基于底层数组的切片: 用来传递数据的通道: 作为一等类型的函数: 可实现 ...

  2. AT2558 [ARC073D] Many Moves

    开始被标签带骗了. 考虑一个\(dp\),\(f[i][j]\)代表有一个棋子在\(x_i\),另外一个\(j\)的最小答案. 那么考虑转移. 如果\(j != x_{i - 1}\) 那么答案自然贡 ...

  3. 洛谷 P6030 - [SDOI2012]走迷宫(高斯消元+SCC 缩点)

    题面传送门 之所以写个题解是因为题解区大部分题解的做法都有 bug(u1s1 周六上午在讨论区里连发两个 hack 的是我,由于我被禁言才让 ycx 代发的) 首先碰到这种期望题,我们套路地设 \(d ...

  4. C/C++ Qt TabWidget 实现多窗体创建

    在开发窗体应用时通常会伴随分页,ToolBar组件可以实现顶部工具栏菜单,每一个ToolBar组件关联到一个TabWidget组件的Tab标签内,这样我们就可以实现一个复杂的多窗体分页结构,此类结构也 ...

  5. 46.Valid Parentheses

    Valid Parentheses My Submissions QuestionEditorial Solution Total Accepted: 106346 Total Submissions ...

  6. 同一局域网,远程连接别人的Mysql数据库

    数据库:MySQL 工具: Navicat, 电脑A连接电脑B的数据库, 确保两部电脑都是在同一个局域网,都是连着同一个路由器,或者连接同一个WiFi, 如果不确定是否为同一个局域网,可以打开cmd, ...

  7. SpringBoot Logback 日志配置

    目录 前言 日志格式 日志输出 日志轮替 日志级别 日志分组 小结 前言 之前使用 SpringBoot 的时候,总是习惯于将日志框架切换为 Log4j2,可能是觉得比较靠谱,也可能年龄大了比较排斥新 ...

  8. day09搭建均衡负载和搭建BBS博客系统

    day09搭建均衡负载和搭建BBS博客系统 搭建BBS博客系统 本次搭建bbs用到的技术 需要用到的: 1.Nginx+Django 2.Django+MySQL 环境准备 主机 IP 身份 db01 ...

  9. 【Reverse】DLL注入

    DLL注入就是将dll粘贴到指定的进程空间中,通过dll状态触发目标事件 DLL注入的大概流程 https://uploader.shimo.im/f/CXFwwkEH6FPM0rtT.png!thu ...

  10. [项目总结]怎么获取TextView行数,为什么TextView获取行数为0?

    1 final TextView textView = new TextView(this); 2 ViewTreeObserver viewTreeObserver = textView.getVi ...