文件锁

在文件已经共享的情况下,当多个用户共同使用时,如何对文件进行访问呢?linux采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。锁分为建议锁和强制锁

建议锁:要求每个上锁文件的进程都要检查是否有锁存在,并尊重已有的锁,一般情况下内核和系统都不使用建议性锁。

强制锁:由内核执行的锁,当一个文件被上锁进行写入的时候,内核将阻止其他任何文件对其进行读写操作,采用强制性锁对性能影响很大,每次读写都必须检查是否有锁存在。

上锁主要有两个函数:lockf()--------对文件施加建议性锁

                                     fcntl()--------可以施加建议性锁和强制性锁,并且可以施加建议性锁

记录锁分为读取锁和写入锁,读取锁是共享的,但写入锁是互斥的,也就是同一时刻只能有一个进程在文件的某个部分添加写入锁,当然文件不能同时加入写入锁和读取锁

ps:fcntl()不仅可以管理文件锁,而且可以获得和设置文件描述符和文件描述符标志,文件描述符的复制等功能,下面就是如何添加记录锁

fcntl()函数语法:




lock结构体的定义:

struct flock
{
    shrot l_type ;
    off_t l_shart ;
    short l_whence ;
    off_t l_len ;
    pid_t l_pid ;
}

lock结构中每个变量含义如下


ps:为了加锁整个文件通常的做法是将l_start设置为0,l_whenec设置为seek_set,l_len设置为0

这里有个使用文件记录锁得例子

文件记录锁的代码:

int lock_set(int fd, int type)
{
    struct flock old_lock, lock;
    lock.l_whence = SEEK_SET ;
    lock.l_start = 0;
    lock.l_len = 0 ;
    lock.l_type = type ;
    lock.l_pid = -1 ;
    /*F_GETLK判断文件是否能根据lock中的描述上锁,如果可以上锁则将flock结构中的l_type设置成F_UNLCK,如果
    不能上锁l_pid设置成拥有文件锁得进程号,其他的不变*/
    fcntl(fd, F_GETLK, &lock) ;
    if (lock.l_type != F_UNLCK)//判断文件不能上锁的原因
    {
        if (lock.l_type == F_RDLCK)//文件有读锁了
        {
            printf("read lock aleady set by %d\n", lock.l_pid) ;
        }
        else if (lock.l_pid = F_WRLCK)//文件有写锁了
        {
            printf("Wirte lock aleady set by %d\n", lock.l_pid) ;
        }
    }
    lock.l_type = type ;//此时肯能已经被F_GETLK修改过
    /*进行阻塞式上锁,F_SETLKW是F_SETLK的阻塞版本,如果没有获取到锁
    就会进入睡眠状态,如果可以获取到锁或者捕捉到信号就会返回*/
    if ((fcntl(fd, F_SETLKW, &lock)))
    {
        printf("lock failed:type = %d\n", lock.l_type) ;
        return 1 ;
    }
    switch(lock.l_type)
    {
        case F_RDLCK:
        {
            printf("read lock set by %d\n", getpid()) ;
        }
        break ;
        case F_WRLCK:
        {
            printf("write lock set by %d\n", getpid()) ;
        }
        break ;
        case F_UNLCK:
        {
            printf("release lock set by %d\n", getpid()) ;
        }
        break ;
        default:
        break ;
    }
    return 0 ;
}

下面是测试实例,先加入写入锁,最后再释放锁得过程。可以打开两个终端进行测试

#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "lock_set.c"
int main()
{
    int fd ;
    fd = open("hello", O_RDWR| O_CREAT, 0644) ;
    if (fd < 0)
    {
        printf("open file error\n") ;
        exit(1) ;
    }
    lock_set(fd, F_WRLCK) ;//给文件加上写入锁
    getchar() ;//从终端获取一个输入字符
    lock_set(fd, F_UNLCK) ;//给文件解锁
    getchar() ;
    close(fd) ;
    exit(0) ;
}

终端1:

   

终端2:


等终端1解锁之后

终端1:


终端2:


可以看出写锁不是共享的,只能有一个 进程添加写锁

同样的原理试验读锁,发现读锁是可以共享的

在一个终端加入读锁,在另一个终端加入写锁也是不行的。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux VFS(Virtual File System)文件是用于在多进程或多线程环境下对文件进行并发访问控制的机制。它可以确保同一时间只有一个进程或线程能够对文件进行写操作,从而避免数据的不一致性和竞争条件的发生。 Linux VFS文件主要有两种类型:共享(读)和独占(写)。共享允许多个进程或线程同时对文件进行读操作,而独占则只允许一个进程或线程对文件进行写操作。 在Linux中,文件是通过fcntl系统调用来实现的。具体而言,可以使用fcntl函数来获取、设置和释放文件。fcntl函数的相关参数包括文件描述符、类型、起始位置和长度等。 以下是一些关于Linux VFS文件的常见问题及回答: 1. 什么是共享和独占? 共享(读)允许多个进程或线程同时对文件进行读操作,不会阻塞其他进程或线程的读操作。独占(写)则只允许一个进程或线程对文件进行写操作,其他进程或线程的读写操作都会被阻塞。 2. 如何获取文件? 可以使用fcntl函数来获取文件。通过设置fcntl函数的参数,可以指定类型、起始位置和长度等信息。 3. 文件的作用是什么? 文件可以确保同一时间只有一个进程或线程能够对文件进行写操作,从而避免数据的不一致性和竞争条件的发生。它在多进程或多线程环境下起到了并发访问控制的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值