python-文件锁

  • 文件锁(fcntl)
    • fcntl这个模块是Python自带的,但Windows没有,可以手工下载fcntl.py文件,然后保存到python的Lib目录下
    • 锁类型(fcntl.flock函数的第二个参数)
    • LOCK_SH: 表示要创建一个共享锁,所有进程没有写访问权限,即使是加锁进程也没有。所有进程有读访问权限,在任意时间内,一个文件的共享锁可以被多个进程拥有。
      LOCK_EX: 表示创建一个排他锁,除加锁进程外其他进程没有对已加锁文件读写访问权限,在任意时间内,一个文件的排他锁只能被一个进程拥有。
      LOCK_UN: 表示删除该进程创建的锁
      LOCK_NB: 如果指定此参数,函数不能获得文件锁就立即返回,否则,函数会等待获得文件锁。LOCK_NB可以同LOCK_SH或LOCK_NB进行按位或(|)运算操作。 fcnt.flock(f,fcntl.LOCK_EX|fcntl.LOCK_NB)
      LOCK_MAND:它主要是用于共享模式强制锁,它可以与 LOCK_READ 或者 LOCK_WRITE 联合起来使用,从而表示是否允许并发的读操作或者并发的写操作(尽管在 flock() 的手册页中没有介绍LOCK_MAND,但是阅读内核源代码就会发现,这在内核中已经实现了)

# -*- coding:utf-8 -*-
'''
锁类型(fcntl.flock函数的第二个参数)
LOCK_SH:  表示要创建一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有 
LOCK_EX:  表示创建一个排他锁,在任意时间内,一个文件的排他锁只能被一个进程拥有 
LOCK_UN:  表示删除该进程创建的锁 
LOCK_MAND:它主要是用于共享模式强制锁,它可以与 LOCK_READ 或者 LOCK_WRITE 联合起来使用,从而
           表示是否允许并发的读操作或者并发的写操作(尽管在 flock() 的手册页中没有介绍 
           LOCK_MAND,但是阅读内核源代码就会发现,这在内核中已经实现了)
'''
import os
import sys
import time
import fcntl
import threading
import random

# 如下例子中,分别加锁和不加锁,结果
#   不加锁时,多个线程间竞争文件写权限,会出现覆盖,导致写内容不可预期(见test.log.withoutlock)
#   加锁时,多个线程间会等待一个线程结束(因为设置的是阻塞锁)后,第二个线程才开始写,不会相互
#       覆盖(见test.log.withlock)
def demo(name="null"):
    fp = open("test.log", "a+")
    cnt = 0
    # 在3s内随机等待一段时间,打乱加锁顺序
    time.sleep(float(random.randint(0, 300)) / 300)
    fcntl.flock(fp, fcntl.LOCK_EX)
    print "call demo by %s" % name

    # 在10s内进行写入,为了避免写入的内容过多,写0.5s,停0.5s
    for i in range(10):
        # 写0.5s
        for i in range(100):
            fp.write("write by %s, %d\n" % (name, cnt))
            cnt += 1
            time.sleep(0.005)

        # 停0.5s
        time.sleep(0.5)
    fcntl.flock(fp, fcntl.LOCK_UN)
    fp.close()


if __name__ == "__main__":
    # 创建3个进程,并发写入
    for cnt in range(3):
        name = "thread_%d" % cnt
        thd = threading.Thread(target=demo, args=(name,))
        thd.start()

未加锁时,线程写入异常
未加锁时,线程写入异常

posted @   木lin木  阅读(6942)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示