linux C语言实现文件锁

flock函数说明

flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作。此函数只能锁定整个文件,无法锁定文件的某一区域。

表头文件 #include<sys/file.h>

定义函数 int flock(int fd,int operation);

参数 operation有下列四种情况:

LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。

LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。

LOCK_UN 解除文件锁定状态。

LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。

单一文件无法同时建立共享锁定和互斥锁定,而当使用dup()或fork()时文件描述词不会继承此种锁定。

返回值 返回0表示成功,若有错误则返回-1,错误代码存于errno。

示例代码

test1.c:

#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE *f = fopen("temp", "w+");
	if(!f)
	{
		printf("error file\n");
		return 0;
	}
	if(0 == flock(fileno(f), LOCK_EX))
	{
		printf("lock...\n");
		getchar();
		fclose(f);
		flock(fileno(f), LOCK_UN);
	}
	else
	{
		printf("lock failed\n");
	}
        return 0;
}

test2.c

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

int main()
{
   FILE *fp;
   char text[]="this is a test!";

   if((fp = fopen("temp", "w+")) == 0)
      printf("can't open file!\n");
   else
   {
      printf("open file success!\n");
	  int  i = flock(fileno(fp), LOCK_SH | LOCK_NB); // 加锁以判断文件是否已经被加锁了
	  printf("%d\n", i);
	  flock(fileno(fp), LOCK_UN);
		
      fwrite(text, strlen(text), 1, fp);
   }

   fclose(fp);
   return 0;
}

测试如下:

在终端1中,运行test1

在终端2中,运行test2

这里主要说明的是在test2.c中,对文件的操作也是要利用加锁来判断文件是否已经被加锁了,

int  i = flock(fileno(fp), LOCK_SH | LOCK_NB);

上面这行代码就是实现这个功能, 注意第二个参数,如果没有LOCK_NB的话,若文件已加锁则会进程阻塞,而上面的方式则不会出现这种问题;另外第一个参数,切勿直接传入(int)fp

i == 0 表示文件加锁成功, i == -1 表示文件已被加锁,不建议执行后续操作

小结:

flock函数的加锁是需要配合使用的,在文件操作之前,首先利用加锁成功与否来判定文件是否被加锁,若成功再进行后续的代码;否则表示文件被锁

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏GreenLeaves

Oracle 锁机制

本文参考自:ORACLE锁机制 1、oracle是一个多用户使用的共享资源,当多个用户并发的操作同一数据行时,那么在oracle数据库中就会存在多个事务操作统一...

24490
来自专栏用户2442861的专栏

mysql table相关命令

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/d...

18720
来自专栏沃趣科技

配置表 | 全方位认识 sys 系统库

在上一篇《初相识 | 全方位认识 sys 系统库》中,我们针对sys 系统库做了一个不痛不痒的开端,是不是觉得太简单了?别急,本期我们将为大家带来系列第二篇《配...

15730
来自专栏java达人

PostgreSQL中的Schema

一个数据库包含一个或多个命名的模式,模式又包含表。模式还包含其它命名的对象,包括数据类型、函数,以及操作符。同一个对象名可以在不同的模式里使用而不会导致冲突;...

22790
来自专栏Snova云数仓

Greenplum中对表批量授权

  DBA在管理数据仓库的时候,往往会创建多个帐号,每个帐号有不同的用途。因此这里就有不同帐号间表授权的需求。

56660
来自专栏个人随笔

MySQL 关于存储过程那点事

存储例程是存储在数据库服务器中的一组sql语句,通过在查询中调用一个指定的名称来执行这些sql语句命令. 简介 SQL语句需要先编译然后执行,而存储过程(Sto...

49880
来自专栏Python爬虫实战

MySQL从零开始:03 基本入门语句

在上一小节中介绍了 MySQL 数据库的安装,接下来终于可以动手操作数据库了。本节内容介绍 MySQL 数据库的一些基本操作当做开胃菜。

9110
来自专栏漫漫深度学习路

opencv(一):Directory(遍历目录下的文件(夹))

opencv 工具类 Directory opencv2 提供了一个 Directory 工具类来帮助读取文件夹中的文件名,这还是挺方便的,因为 目前常用的 c...

25770
来自专栏木头编程 - moTzxx

后台 配置页面功能设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

77440
来自专栏程序猿

SQL注入分析服务器类型

分析数据库服务器类型 一般来说,ACCESS与SQL-SERVER是最常用的数据库服务器,尽管它们都支持T-SQL标准,但还有不同之处,而且不同的数据库有不同的...

34160

扫码关注云+社区

领取腾讯云代金券