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

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. js中Math.round、parseInt、Math.floor和Math.ceil小数取整总结

    Math.round.parseInt.Math.floor和Math.ceil 都可以返回一个整数,具体的区别请看下面的总结. 一.Math.round 作用:四舍五入,返回参数+0.5后,向下取整 ...

  2. LintCode Singleton

    Singleton 3 大要素: 1.有private static的句柄(成员变量即field) 2. constructor 必须为private 3.有public static的getInst ...

  3. mysql 把文件中的sql语句导入到mysql中

    mysql -uroot -proot -Dcollege</home/wwwroot/default/data/xlxxb_2014-10-16.txt;

  4. 《C与指针》第九章练习

    本章问题 1.C语言缺少显示的字符串数据类型,这是一个优点还是一个缺点? answer: (这个问题存在争论(尽管我有一个结论))目前这个方法的优点是字符数组的效率和访问的灵活性,它的缺点是有可能引起 ...

  5. linux之ps命令

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...

  6. 51nod-1732 婚姻介绍所(后缀数组)

    题目大意:回答任意两个子串的最长公共前缀. 题目分析:后缀数组的模板题.但是输入输出都要外挂. 代码如下: # include<iostream> # include<cstdio& ...

  7. spring技术核心概念纪要

    一.背景 springframework 从最初的2.5版本发展至今,期间已经发生了非常多的修正及优化.许多新特性及模块的出现,使得整个框架体系显得越趋庞大,同时也带来了学习及理解上的困难. 本文阐述 ...

  8. 怎样用JS获取ASP.NET服务器控件的客户端ID

    虽然简单,不过曾经困扰多时,还是记录一下吧. 来源:http://mou518.blog.163.com/blog/static/1756052222010111434428828/ 因为经常服务器控 ...

  9. php和js一起实现倒计时功能

    里获取的php服务端的时间 纯JS是获取客服端时间! <?php //php的时间是以秒算.js的时间以毫秒算 date_default_timezone_set('PRC'); //date_ ...

  10. Java多线程——同步(一)

    好习惯要坚持,这是我第二篇博文,任务略重,但是要坚持努力!!! 1.竞争条件 首先,我们回顾一下<Java核心技术卷>里讲到的多线程的"竞争条件".由于各线程访问数据的 ...