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

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秒时间
    
    //打开文件
    if ((fp = fopen("./test.ok", "r+b")) == NULL) 
        printf("file open error!\n");     //给该文件加锁
    if (flock(fp->_fileno, LOCK_EX) != ) 
        printf("file lock by others\n");     //进入循环,加锁时间为20秒,打印倒计时
    while() 
    {   
        printf("%d\n", i--);
        sleep();
        if (i == )
            break;
    }     //20秒后退出,关闭文件
    fclose(fp);     //文件解锁
    flock(fp->_fileno, LOCK_UN);
    return ;
}

文件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   = ;
    
    //打开文件
    if ((fp = fopen("./test.ok", "r+b")) == NULL) 
        printf("file open error!\n");     flock(fp->_fileno, LOCK_EX); //文件加锁     while() //进入循环
    {   
        printf("%d\n", i++);
        sleep();
    }     fclose(fp); //关闭文件     flock(fp->_fileno, LOCK_UN); //释放文件锁     return ;

 首先运行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!\n");
    //给该文件加锁
    if (flock(fp, LOCK_NB|LOCK_EX) != 0)
    {
        printf("file lock fail \n");
            //进入循环,加锁时间为20秒,打印倒计时
    }
    else
    {
            while(1)
            {
                printf("倒计时%d秒\n", i--);
                sleep(1);
                if (i == 0)
                {
                   printf("倒计时结束,程序退出  !\n", 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!\n");
    flock(fp, LOCK_UN); //释放文件锁
    if(flock(fp, LOCK_EX) != 0) //文件加锁
    {
        printf("gei wenjian lock~~ \n");
    }
    else
    {
            while(1) //进入循环
            {
                printf("前进到第%d秒\n", i++);
                sleep(1);
                if(i == 20)
                    break;
            }
    }
    fclose(fp); //关闭文件
    flock(fp, LOCK_UN); //释放文件锁
    return 0;
}

测试竟然不成功。

Linux 文件锁的更多相关文章

  1. Linux文件锁flock

    Linux文件锁flock 在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock. flock,建议性锁 ...

  2. linux文件锁flock【转】

    转自: https://www.cnblogs.com/kex1n/p/7100107.html linux文件锁flock   在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要 ...

  3. 每天进步一点点——Linux文件锁编程flock

    转载请注明出处:http://blog.csdn.net/cywosp/article/details/30083015 1. 场景概述     在多线程开发中.相互排斥锁能够用于对临界资源的保护,防 ...

  4. Linux文件锁学习-flock, lockf, fcntl

    参考  linux中fcntl().lockf.flock的区别 这三个函数的作用都是给文件加锁,那它们有什么区别呢? 首先flock和fcntl是系统调用,而lockf是库函数.lockf实际上是f ...

  5. linux文件锁的应用,POSIX,unix标准,linux标准

    1. perl,flock加锁.java也能加锁. 2. 先创建文件并打开,才能加锁(写打开?). 3. 可以用于判断进程是否一直在运行(用另一进程判断),如果锁一直在,则进程在:锁不在,则原进程或意 ...

  6. Linux文件锁【转】

    本文转载自:http://blog.csdn.net/dragon_li_chen/article/details/17147911 一.文件锁的分类: 翻阅参考资料,你会发现文件锁可以进行很多的分类 ...

  7. linux 文件锁flock,lockf,fcntl

    1.flock,lockf,fcntl之间区别 先上结论:flock是文件锁,锁的粒度是整个文件,就是说如果一个进程对一个文件加了LOCK_EX类型的锁,别的进程是不能对这个文件加锁的. lockf是 ...

  8. linux文件锁

    http://blog.chinaunix.net/uid-25324849-id-3077304.html 在SHELL中实现文件锁,有两种简单的方式.(1)一是利用普通文件,在脚本启动时检查特定文 ...

  9. Linux文件锁flock ,检测进程是否已经存在

    在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock.  头文件:#include<sys/fil ...

随机推荐

  1. Map/Reduce 工作机制分析 --- 数据的流向分析

    前言 在MapReduce程序中,待处理的数据最开始是放在HDFS上的,这点无异议. 接下来,数据被会被送往一个个Map节点中去,这也无异议. 下面问题来了:数据在被Map节点处理完后,再何去何从呢? ...

  2. Tuple方法

    组元是C# 4.0引入的一个新特性,编写的时候需要基于.NET Framework 4.0或者更高版本.组元使用泛型来简化一个类的定义. public class Point { public int ...

  3. 防刷新jq左侧滚动条导航展示

    html代码: <div class="fangchan_navcont">        <div class="fangchan_nav" ...

  4. 图论--最近公共祖先问题(LCA)模板

    最近公共祖先问题(LCA)是求一颗树上的某两点距离他们最近的公共祖先节点,由于树的特性,树上两点之间路径是唯一的,所以对于很多处理关于树的路径问题的时候为了得知树两点的间的路径,LCA是几乎最有效的解 ...

  5. 【递归】斐波那契数列第n个数

    递归.递推计算斐波那契数列第n项的值: #include <stdio.h> long long fact(int n); //[递推]计算波那契数列第n个数 long long fact ...

  6. Jetty与Tomcat的区别 转

    Jetty与Tomcat的区别 由于没有研究过Tomcat,所以区别不好说,这里暂时就网上的一些言论和自己所了解到的一些总结下(摘自于许令波). Jetty 的架构从前面的分析可知,它的所有组件都是基 ...

  7. 干货:结合Scikit-learn介绍几种常用的特征选择方法

    原文  http://dataunion.org/14072.html 主题 特征选择 scikit-learn 作者: Edwin Jarvis 特征选择(排序)对于数据科学家.机器学习从业者来说非 ...

  8. 用脚本处理utf8的文本文件

    filename="C:\Users\Administrator\Desktop\soft\x.txt" filename2="C:\Users\Administrato ...

  9. 【python】类的访问限制

    在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的na ...

  10. Matlab绘制幅值谱和相位谱

    1. 对于直接给出频响函数的情况 这里以滑动平均的频响函数作为例子,滑动窗口为[0, 4]. 上式中M2=4. >> w=0:0.001:2*pi; >> h1=1-exp(- ...