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

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;
    ;    //20秒时间
    
    ) 
        printf() 
    {   
        printf();
        )
            ;
}

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

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

;
    
    ) );
    }

    fclose(fp); ;
} 

 首先运行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.chinaunix.net/uid-25324849-id-3077304.html 在SHELL中实现文件锁,有两种简单的方式.(1)一是利用普通文件,在脚本启动时检查特定文 ...

  7. NIO文件锁FileLock

    目录 <linux文件锁flock> <NIO文件锁FileLock> <java程序怎么在一个电脑上只启动一次,只开一个进程> 文件锁可以是shared(共享锁) ...

  8. 【腾讯Bugly干货分享】Android进程保活招式大全

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8 作者:腾讯——张兴华 目前市面上 ...

  9. Android 进程保活招式大全

    目前市面上的应用,貌似除了微信和手Q都会比较担心被用户或者系统(厂商)杀死问题.本文对 Android 进程拉活进行一个总结. Android 进程拉活包括两个层面: A. 提供进程优先级,降低进程被 ...

随机推荐

  1. (转)HTTP 长连接和短连接

    1. HTTP协议与TCP/IP协议的关系 HTTP的长连接和短连接本质上是TCP长连接和短连接.HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议.IP协议主要解决网络路由和寻址问 ...

  2. 个人博客作业week7

    个人阅读作业week7 一.瀑布 软件工程的瀑布模型是1970年由Winston Royce提出来的,即软件的开发按照一个严格的.顺序的.单次的瀑布流开发周期.例如需求分析阶段.概要设计阶段.详细设计 ...

  3. dns泛解析漫谈

    比如说:http://www.aaa.com/ 指向10.10.1.1,ftp.aaa.com/ 指向10.10.2.2,如果这时候客户访问的是aaa.com或者error.aaa.com (这里er ...

  4. Java集合涉及的类(代码)

    Customer: public class Customer implements Comparable{        private Integer customerId;        pri ...

  5. C语言中的结构体和C++中的结构体以及C++中类的区别

    c++中结构体可以定义一个函数 C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一. ...

  6. Robot Framework与Web界面自动化测试学习笔记:简单例子

    假设环境已经搭建好了.这里用RIDE( Robot Framework Test Data Editor)工具来编写用例.下面我们对Robot Framework简称rf. 我们先考虑下一个最基本的登 ...

  7. Java中设计模式之工厂模式-4

    一.工厂模式由来 1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用. 2)简单工厂模式:后来出现工业革命.用户不用去创建宝马车.因为客户有 ...

  8. 委托(C#)

    委托,delegate 关键字用于声明一个引用类型,该引用类型可用于封装命名方法或匿名方法.委托类似于 C++ 中的函数指针:但是,委托是类型安全和可靠的.委托类型声明的格式如下: public de ...

  9. 因数(factor)

    一个最基本的算数法则就是大于1的整数都能用1个或多个素数相乘的形式表示出来.当然,有多种质因子排列方案 如: 10=2×5=5×2    20=5×2×2=2×5×2=2×2×5 用f(k)表示k的质 ...

  10. PhpSpreadsheet处理表格

    介绍:PhpSpreadsheet是PHPExcel的下一个版本.它打破了兼容性,大大提高了代码库质量(命名空间,PSR合规性,最新PHP语言功能的使用等).由于所有努力都转移到了PhpSpreads ...