文件IO操作之文件锁fcntl()函数

linux是多用户的操作系统,在实际的应用中不可避免的会出现多个用户(或是多个进程)共同使用、操作一个文件的情况,这时,linux通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。

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

linux中实现上锁的函数lockf() — 施加建议性锁
fcntl() — 施加建议性锁,或是强制锁,或是对文件某一记录上锁(记录锁)

记录锁 —- 读取锁(共享锁):能够使多个进程都能在文件的同一部分建立读取锁
—- 写入锁(排斥锁):在任何时候只能有一个进程在文件的某个部分建立写入锁。
在文件的同一部分不能同时建立读取锁和写入锁。

fcntl()函数:
这里写图片描述
struct flock 结构体

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

这里写图片描述
如果要加锁整个文件,通常的方法是将l_start 设置为0,l_whence 设置为SEEK_SET,l_len设置为0.
设置文件锁部分代码lock_set.c:每次设置前都要查询文件是否已被上锁

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;

    /*file is locked?*/
    fcntl(fd,F_GETLK,&lock);
    if(lock.l_type != F_UNLCK)
        {
            /*why cannot lock the file?*/
            if(lock.l_type == F_RDLCK)//have a rd lock
                {
                    printf("Read lock already set by %d\n",lock.l_pid);
                }
            else if(lock.l_type == F_WRLCK)//have a wr lock
                {
                    pritnf("write lock already set by %d\n",lock.l_pid);
                }

        }

    /*l_type may have been modified by F_GETLCK*/
    lock.l_type = type;

    if(fcntl(fd,F_SETLKW,&lock)<0)
        {
            printf("Lock failed:type=%d\n",lock.l_type);
            return 1;
        }

上写入锁:

#include "lock_set.c"

int main()
{
    int fd;

    /*open file*/
    fd = open("hello",O_RDWR|O_CREAT,0644);
    if(fd<0)
        {
            printf("Open file error\n")
            exit(1);
        }
    /*lock the file*/
    lock_set(fd, F_WRLCK);
    getchar();
    /*release the file*/
    lock_set(fd, F_UNLCK);
    getchar();

    close(fd);
    exit(0);
}

在两个终端中运行write_lock,
终端1:
root@jwx-merit:/home/jwx/work/fileLock# ./write_lock
Wrtie lock set by 4823

Release lock by 4823

终端2:
root@jwx-merit:/home/jwx/work/fileLock# ./write_lock
write lock already set by 4823
Wrtie lock set by 4959

Release lock by 4959
由此可见,同一时刻只能有一个写入锁存在。

上读取锁;

#include "lock_set.c"

int main()
{
    int fd;

    /*open file*/
    fd = open("hello",O_RDWR|O_CREAT,0644);
    if(fd<0)
        {
            printf("Open file error\n")
            exit(1);
        }
    /*lock the file*/
    lock_set(fd, F_RDLCK);
    getchar();
    /*release the file*/
    lock_set(fd, F_UNLCK);
    getchar();

    close(fd);
    exit(0);
}

在两个终端运行读取锁,
终端1:
root@jwx-merit:/home/jwx/work/fileLock# ./read_lock
Read lock set by 4965

Release lock by 4965
终端2:
root@jwx-merit:/home/jwx/work/fileLock# ./read_lock
Read lock set by 4968

Release lock by 4968
可见,读取锁可以同时被4965 和 4968 两个进程设置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值