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')对该文件加 ...
随机推荐
- Atcoder Grand Contest 001 D - Arrays and Palindrome(构造)
Atcoder 题面传送门 洛谷题面传送门 又是道思维题,又是道把我搞自闭的题. 首先考虑对于固定的 \(a_1,a_2,\dots,a_n;b_1,b_2,\dots,b_m\) 怎样判定是否合法, ...
- Codeforces 750E - New Year and Old Subsequence(线段树维护矩阵乘法,板子题)
Codeforces 题目传送门 & 洛谷题目传送门 u1s1 我做这道 *2600 的动力是 wjz 出了道这个套路的题,而我连起码的思路都没有,wtcl/kk 首先考虑怎样对某个固定的串计 ...
- 8.Maximum Depth of Binary Tree
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...
- 通过yum安装 memcache
. 通过yum安装 复制代码代码如下: yum -y install memcached#安装完成后执行:memcached -h#出现memcached帮助信息说明安装成功 2. 加入启动服务 复制 ...
- Beautiful Soup解析库的安装和使用
Beautiful Soup是Python的一个HTML或XML的解析库,我们可以用它来方便地从网页中提取数据.它拥有强大的API和多样的解析方式.官方文档:https://www.crummy.co ...
- typora 图床配置方法
学习计算机的同学,在日常学习中难免会记笔记,写文档.相信大家记笔记大部分使用的都是 Markdown 吧,如果到现在还没接触,那我强烈建议你去学习一下,大概几分钟就可以搞定它. 注:下文用到的所有软件 ...
- 解决CentOS7 docker容器映射端口只监听ipv6的问题
问题现象 docker容器起来以后,查看9100端口监听情况,如下图: $ ss -lntp State Recv-Q Send-Q Local Address:Port Peer Address:P ...
- 日常Java 2021/11/21
Java文档注释 Java支持三种注释方式.前两种分别是Ⅱ和/产*,第三种被称作说明注释,它以产开始,以*I结束.说明注释允许你在程序中嵌入关于程序的信息.你可以使用javadoc工具软件来生成信息, ...
- absent, absolute
absent 1. A teacher asked in a class who killed Abraham Lincoln. A blonde said "It wasn't me, I ...
- EDA简介
Electronic design automation (EDA), also referred to as electronic computer-aided design (ECAD),[1] ...