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.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 加锁模块的更多相关文章
- python 中给文件加锁——fcntl模块
如果没有fcntl模块则用 sudo pip install fcntl安装 模块简单说明: 打开文件,不存在则创建之 f = open('./test','w') fcntl.flock(f,fcn ...
- 文件锁fcntl
一.python中的文件锁 我们在写python应用的时候,当涉及到多个进程向同一个文件write(或者read)的情况,如果几个进程同时都对这个文件进行写操作,那么文件的内容就会变得非常混乱,这个时 ...
- Linux文件锁学习-flock, lockf, fcntl
参考 linux中fcntl().lockf.flock的区别 这三个函数的作用都是给文件加锁,那它们有什么区别呢? 首先flock和fcntl是系统调用,而lockf是库函数.lockf实际上是f ...
- 文件锁-fcntl flock lockf
这三个函数的作用都是给文件加锁,那它们有什么区别呢? 首先flock和fcntl是系统调用,而lockf是库函数.lockf实际上是fcntl的封装,所以lockf和fcntl的底层实现是一样的,对文 ...
- python-文件锁
文件锁(fcntl) fcntl这个模块是Python自带的,但Windows没有,可以手工下载fcntl.py文件,然后保存到python的Lib目录下 锁类型(fcntl.flock函数的第二个参 ...
- 非阻塞io与记录锁
非阻塞io 1.对比 阻塞io的例子:scanf从终端获取输入时,如果不输入程序就会一直停在那; 对一个已经有写锁的文件请求读时, 会一直空等直到前面的进程释放锁... 非阻塞的例子:读取文件内容, ...
- 遵循PEP8风格
遵循PEP8风格 在编写python代码的时候我们应该采用统一的风格来编写代码,可以使代码更加容易读懂.采用和其他程序员统一的编码风格来写代码,也可以使项目更利于多人协作开发.即便代码只有你自己能看懂 ...
- 捉虫日记 | MySQL 5.7.20 try_acquire_lock_impl 异常导致mysql crash
背景 近期线上MySQL 5.7.20集群不定期(多则三周,短则一两天)出现主库mysql crash.触发主从切换问题,堆栈信息如下: 从堆栈信息可以明显看出,在调用 try_acquire_loc ...
- python中给程序加锁之fcntl模块的使用
python 中给文件加锁——fcntl模块import fcntl 打开一个文件##当前目录下test文件要先存在,如果不存在会报错.或者以写的方式打开f = open('./test')对该文件加 ...
随机推荐
- 部署vue项目到Linux服务器
案例一 vue-cli构建vue3项目,将项目上传到Linux服务器,服务器安装node,并启动vue项目 首先本地有一个vue项目,启动后可正常访问 本地打包后,也可直接访问 若打包后的index. ...
- Java培训班4个月有用吗?
很多想学Java都会经历这样一个选择,是自学还是报班?自学的话需要一步步摸索,从无到有硬啃下来,时间没保证:可如果报班的话,目前市面上五花八门的培训机构又是鱼龙混杂,并且现在越来越多的培训机构宣称&q ...
- 难道你还不知道Spring之事务的回滚和提交的原理吗,这篇文章带你走进源码级别的解读。
上一篇文章讲解了获取事务,并通过获取的connection设置只读,隔离级别等:这篇文章讲事务剩下的回滚和提交. 事务的回滚处理 之前已经完成了目标方法运行前的事务准备工作.而这些准备工作的最大目的无 ...
- Codeforces 429E - Points and Segments(欧拉回路)
Codeforces 题面传送门 & 洛谷题面传送门 果然我不具备融会贯通的能力/ll 看到这样的设问我们可以很自然地联想到这道题,具体来说我们可以通过某种方式建出一张图,然后根据" ...
- R语言矩阵相关性计算及其可视化?
目录 1. 矩阵相关性计算方法 base::cor/cor.test psych::corr.test Hmisc::rcorr 其他工具 2. 相关性矩阵转化为两两相关 3. 可视化 corrplo ...
- python-django-事务使用
其中任何一个步骤失败都不行, 失败则回滚 在一对一的模型下 例如,用户基本信息和用户详细信息 必须两个一起添加用户信息才算成功 通过位置参数来实现 手动控制事务 def page_trans_hand ...
- jQuery ajax常用示例
总结一下jQuery ajax常用示例 $.ajax({ type: "post", //类型get,post url: urls, //链接地址 data:{"id&q ...
- vc控制台程序关闭事件时的正确处理方式
百度可以找到很多关于这个问题解决的方法 关键控制台API函数:SetConsoleCtrlHandler 在支持C++ 11以上的编译器中,你可以这么做. SetConsoleCtrlHandler( ...
- Linux常用命令之文件权限管理
Linux文件权限管理1.改变文件或目录的权限:chmod命令详解命令名称:chmod命令所在路径:/bin/chmod执行权限:所有用户语法:chmod [{ugoa}{+-=}{rwx}] [文件 ...
- linux vi(vim)常用命令汇总(转)
前言 首先解析一个vim vi是unix/linux下极为普遍的一种文本编辑器,大部分机器上都有vi的各种变种,在不同的机器上常用不同的变种软件,其中vim比较好用也用的比较广泛.vim是Vi Imp ...