• Linux 文件锁


    当多个进程同时访问操作同一个文件时,我们怎么保证文件数据的正确性。

    linux通常采用的方法是文件上锁,来避免共享资源的产生竞争状态。

    文件锁包括建议性锁强制性的锁:

    建议性的锁 :顾名思义,相对温柔一些,在对文件进行锁操作时,会检测是否已经有锁存在,并且尊重已有的锁。在一般的情况下,内核和系统都不使用建议锁。

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

    在linux中对文件进行锁操作,可以使用lockf()和fcntl()这两个函数:

    前者对文件施加建议性锁,后者为两种锁都行。另外fcntl还可以对文件的某一记录上锁。
    fcntl函数原型:

    int fcntl(  int fd,  int cmd,  struct flock *lock  );

    fd为文件描述符

    cmd为一些命令参数

    flcok结构体用来设置记录锁的具体状态。

    fcntl() 对已打开的文件描述符进行操作,并根据命令参数的不同能够执行不同的任务。

    关于文件锁的几个命令选项如下:

    F_GETLK 根据lock参数值,决定是否上文件锁

    F_SETLK 设置lock参数值的文件锁

    F_SETLKW 这是 F_GETLK的阻塞版本,在无法获取锁时,会进入睡眠状态
        flock结构体的定义如下:
         struct flock {
                   short l_type;
                   off_t l_start;
                   short l_whence;
                   off_t l_len;
                   pid_t l_pid;
         }

    l_type有三个选项:    

    F_RDLCK  : 共享锁,只读用         

    F_WRLCK : 独占锁(写操作锁)       

    F_UNLCK  : 解除锁定

                      l_start 为相对位移量
                      l_whence 必须是以下几个值之一( 在 unistd.h 中定义):
                      SEEK_SET : 文件开始位置
                      SEEK_CUR: 文件当前位置
                      SEEK_END: 文件末尾位置
                       l_len 加锁的长度
                       l_pid当前文件操作的进程id号


    文件2 test01.c,代码如下:
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)

    {

        FILE  *fp = NULL;
        int   i   = 20;    //20秒时间
        
        //打开文件
        if ((fp = fopen("./test.ok""r+b")) == NULL) 
            printf("file open error! ");

        //给该文件加锁
        if (flock(fp->_fileno, LOCK_EX) != 0
            printf("file lock by others ");

        //进入循环,加锁时间为20秒,打印倒计时
        while(1
        {   
            printf("%d ", i--);
            sleep(1);
            if (i == 0)
                break;
        }

        //20秒后退出,关闭文件
        fclose(fp);

        //文件解锁
        flock(fp->_fileno, LOCK_UN);
        return 0;
    }

     文件2 test02.c,代码如下:

    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main(void)
    {
        FILE *fp = NULL;
        int  i   = 0;
        
        //打开文件
        if ((fp = fopen("./test.ok""r+b")) == NULL) 
            printf("file open error! ");

        flock(fp->_fileno, LOCK_EX); //文件加锁

        while(1//进入循环
        {   
            printf("%d ", i++);
            sleep(1);
        }

        fclose(fp); //关闭文件

        flock(fp->_fileno, LOCK_UN); //释放文件锁

        return 0;
    } 

     首先运行test01.c,紧接着运行test02.c(运行test01.c后20秒内要运行test02.c否则看不到现象

     现象:

    test01.c执行起来以后,开始倒计时。

    此时运行test02.c会阻塞在加锁处。

    当test01.c运行20秒后关闭文件,并释放文件锁后,test02.c会开始运行。

    测试:

     1.************************************

    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
        FILE  *fp = NULL;
        int   i   = 20;    //20秒时间
        //打开文件
        if ((fp = fopen("./test.ok", "r+")) == NULL)
            printf("file open error! ");
        //给该文件加锁
        if (flock(fp, LOCK_NB|LOCK_EX) != 0)
        {
            printf("file lock fail ");
                //进入循环,加锁时间为20秒,打印倒计时
        }
        else
        {
                while(1)
                {
                    printf("倒计时%d秒 ", i--);
                    sleep(1);
                    if (i == 0)
                    {
                       printf("倒计时结束,程序退出  ! ", i--);
                       break;
                    }
                }
        }
        //20秒后退出,关闭文件
        fclose(fp);
        //文件解锁
        flock(fp, LOCK_UN);
        //20秒后退出,关闭文件
        //fclose(fp);
        return 0;
    }

     2.************************************************

    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
        FILE *fp = NULL;
        int  i   = 0;
        //打开文件
        if ((fp = fopen("./test.ok", "r+b")) == NULL)
            printf("file open error! ");
        flock(fp, LOCK_UN); //释放文件锁
        if(flock(fp, LOCK_EX) != 0) //文件加锁
        {
            printf("gei wenjian lock~~ ");
        }
        else
        {
                while(1) //进入循环
                {
                    printf("前进到第%d秒 ", i++);
                    sleep(1);
                    if(i == 20)
                        break;
                }
        }
        fclose(fp); //关闭文件
        flock(fp, LOCK_UN); //释放文件锁
        return 0;
    }

     测试竟然不成功。


     

  • 相关阅读:
    【JZOJ5603】【NOI2018模拟3.27】Xjz
    【JZOJ5605】【NOI2018模拟3.26】Arg
    【agc004e】Salvage Robots
    【agc004c】AND Grid
    【agc004d】Teleporter
    【agc002f】Leftmost Ball
    【agc002d】Stamp Rally
    【arc068F】Solitaire
    51nod 1172 Partial Sums V2
    快速数论变换NTT模板
  • 原文地址:https://www.cnblogs.com/client-server/p/5530719.html
Copyright © 2020-2023  润新知