#!/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. 洛谷 P3644 [APIO2015]八邻旁之桥(对顶堆维护中位数)

    题面传送门 题意: 一条河将大地分为 \(A,B\) 两个部分.两部分均可视为一根数轴. 有 \(n\) 名工人,第 \(i\) 名的家在 \(x_i\) 区域的 \(a_i\) 位置,公司在 \(y ...

  2. 执行脚本source 和 . 和sh 的区别是什么

    "source"和"."的功能是一样的,可以调用脚本,并将脚本里的函数也传递到当前的脚本或者解释器中,即不会开启新的bash而是在当前bash中运行. &quo ...

  3. 57-Palindrome Linked List

    Palindrome Linked List My Submissions QuestionEditorial Solution Total Accepted: 46990 Total Submiss ...

  4. Oracle完整的压测记录

    问题描述:对oracle进行一次完整的数据压测,从制造数据到压测的过程,路上踩了一些坑,现在分享出来 1.下载swingbenh软件,一个比较好用的oracle压测软件 2.利用oewizard工具( ...

  5. Redis | 第9章 Lua 脚本与排序《Redis设计与实现》

    目录 前言 1. Lua 脚本 1.1 Redis 创建并修改 Lua 环境的步骤 1.2 Lua 环境协作组件 1.3 EVAL 命令的实现 1.4 EVALSHA 命令的实现 1.5 脚本管理命令 ...

  6. 开发安卓记账本-HelloAndroid的完成

    这个寒假要完成一个家庭记账本软件的开发,今天完成了Android Studio的安装与第一个安卓应用的运行(HelloAndroid) 下图是效果: 1.Android Studio的安装 可直接百度 ...

  7. idea Error : java 不支持发行版本5

    问题描述 在Intellij idea中新建了一个Maven项目,运行时报错如下:Error : java 不支持发行版本5 解决 1.在Intellij中点击"File" --& ...

  8. python web工程师跳巢攻略

    python web工程师跳巢攻略 流程 一面问基础 二面问项目 三面问设计(经验) web请求的流程 浏览器 负载均衡 web框架 业务逻辑 数据库缓存 后端技术栈 python语言基础 语言特点 ...

  9. Sharding-JDBC 实现水平分库分表

    1.需求分析

  10. Shell学习(三)——Shell条件控制和循环语句

    参考博客: [1]Shell脚本的条件控制和循环语句 一.条件控制语句 1.if语句 1.1语法格式: if [ expression ] then Statement(s) to be execut ...