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

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. GT 940M 到底怎么样! 768的可以 1080的不要用了

    而对于目前的市场来看,NVIDIA独显无疑是占据了产品端的绝对主力,9系列独显也已经全面上市,但除了大家熟悉的GTX级之外,入门级的更新也同样对入门级玩家有着至关重要的意义,其中最具代表性的莫过于今天 ...

  2. UIApplication的使用

    //// UIApplication的使用//  IOS笔记////  Created by **** on ****.//  Copyright © 2013年 ***. All rights re ...

  3. git使用流程

    1,配置sshkey: ssh-keygen -t rsa -C "Github 的注册邮箱" //创建本地 ssh 在 Github 中添加这个 sshkey : 复制  id_ ...

  4. Android AChartEngine 去除折线图黑边

    通常使用AChartEngine画出的折线图,如果背景不是黑色,则会在折线图的坐标轴旁边出现黑边,如图所示: 试了好多设置,最后终于发现,去除黑边的设置是: mRenderer.setMarginsC ...

  5. 【Oozie】安装配置Oozie

    安装和配置Oozie Oozie用于Hadoop的工作流配置: 参考链接: <Install and Configure Apache Oozie Workflow Scheduler for ...

  6. filter and listener

    Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层. 使用 Serv ...

  7. spring java 获取webapp下文件路径

    spring java 获取webapp下文件路径 @RequestMapping("/act/worldcup_schedule_time/imgdownload") @Resp ...

  8. 核心动画和UIView动画的区别

    核心动画和UIView动画的区别 1.核心动画制作用在Layer 2.核心动画的修改的属性都是假象,他的真实位置没有发生变化()

  9. NGUI之UILabel

    重要属性说明 overflow: Shrink Content: 意味着内容会自动被缩小以便适应区域.它在你使用动态字体的同时使用Keep      Crisp设置时有效,让字体变小,而不是缩放内容. ...

  10. Blackfin DSP(六):BF533的SPORT接口

    1.特性 bf533有两个SPORT口(synchronous serial Port),即同步串行接口.完全独立的接收和发送通道,且每个通道都具有缓冲,最高速度可达SCLK/2.最大支持32bit字 ...