嵌入式Linux基础学习笔记-文件IO编程-文件锁(1)

文件锁-文件共享

  • 共享资源竞争问题的解决方法:文件锁。
  • 文件锁包括
    • 建议性锁 要求每个上锁文件的进程都要检查是否有锁存在,并且尊重 已有的锁
    • 强制性锁 由内核执行的锁,当一个文件被上锁进行写入操作的时候, 内核将阻止其他任何文件对其进行读写操作。
  • 文件上锁的函数
    • lockf()
      用于对文件施加建议性锁
    • fcntl()
      不仅可以施加建议性锁,还可以施加强制锁。同时还能对文 件的某一记录上锁,也就是记录锁。
  • 记录锁可分为
    • 读取锁: 又称为共享锁,能够使多个进程都能在文件的同一部分建立 读取锁。
    • 写入锁: 又称为排斥锁,在任何时刻只能有一个进程在文件的某个部 分上建立写入锁。
  • 注:在文件的同一部分不能同时建立读取锁和写入锁。

fcntl()函数格式

fcntl()函数格式

fcntl函数原型:
int fcntl(int fd, int cmd);  
int fcntl(int fd, int cmd, long arg);  
int fcntl(int fd, int cmd ,struct flock* lock);  
flock结构
struct flock
{
    short l_type;		/*锁的类型*/  
    off_t l_start;		/*偏移量的起始位置:SEEK_SET,SEEK_CUR,SEEK_END*/  
    short l_whence;	 	/*加锁的起始偏移*/  
    off_t l_len;		/*上锁字节*/  
    pid_t l_pid;		/*锁的属主进程ID */  
}
  • flock结构变量取值

在这里插入图片描述

  • 上手代码:
1. lock_set.c实现文件记录锁功能:
/* lock_set.c */
int lock_set(int fd, int type)
{
	struct flock old_lock, lock;
	lock.l_whence = SEEK_SET;
	lock.l_start = 0;
	lock.l_len = 0;
	lock.l_type = type;
	lock.l_pid = -1;
	
	/* 判断文件是否可以上锁 */
	fcntl(fd, F_GETLK, &lock);
	
	//文件已有锁
	if (lock.l_type != F_UNLCK)
	{
		/* 判断文件不能上锁的原因 */
		if (lock.l_type == F_RDLCK) /* 该文件已有读取锁 */
		{
			printf("Read lock already set by %d\n", lock.l_pid);
		}
		else if (lock.l_type == F_WRLCK) /* 该文件已有写入锁 */
		{
			printf("Write lock already set by %d\n", lock.l_pid);
		}			
	}
	
	/* l_type 可能已被F_GETLK修改过 */
	lock.l_type = type;
	
	/* 根据不同的type值进行阻塞式上锁或解锁 */
	if ((fcntl(fd, F_SETLKW, &lock)) < 0)
	{
		printf("Lock failed:type = %d\n", lock.l_type);
		return 1;
	}
		
	switch(lock.l_type)
	{
		case F_RDLCK:
		{
			printf("Read lock set by %d\n", getpid());
		}
		break;

		case F_WRLCK:
		{
			printf("Write lock set by %d\n", getpid());
		}
		break;

		case F_UNLCK:
		{
			printf("Release lock by %d\n", getpid());
			return 1;
		}
		break;

		default:
		break;
	}/* end of switch  */
	
	return 0;
}
2. 文件写入锁的测试用例 write_lock.c:

创建一个hello文件,之后对其上写入锁,键盘输入任意一个字符后解除写入锁。

/* write_lock.c */
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "lock_set.c"

int main(void)
{
	int fd;
	
	/* 首先打开文件 */
	fd = open("hello",O_RDWR | O_CREAT, 0644);
	if(fd < 0)
	{
		printf("Open file error\n");
		exit(1);
	}
	
	/* 给文件上写入锁 */
	//调用lock_set函数
	lock_set(fd,F_WRLCK);
	getchar();	//输入任意字符
	
	/* 给文件解锁 */
	lock_set(fd,F_UNLCK);
	getchar();	//
	
	close(fd);	
	exit(0);
}

Write_lock-1

补充笔记:关于Linux权限
Linux 系统中采用三位十进制数表示权限,如0755, 0644.
ABCD
A- 0, 表示十进制
B-用户
C-组用户
D-其他用户
 
---  -> 0   (no excute , no write ,no read)
--x  -> 1   excute, (no write, no read)
-w-  -> 2   write 
-wx  -> 3   write, excute
r--  -> 4   read
r-x  -> 5   read, excute
rw-  -> 6   read, write , 
rwx  -> 7   read, write , excute
 
0755->即用户具有读/写/执行权限,组用户和其它用户具有读写权限;
0644->即用户具有读写权限,组用户和其它用户具有只读权限;
3. 在两个终端上运行./write_lock,查看运行结果

在这里插入图片描述在这里插入图片描述

4. 编写文件读取锁的测试用例read_lock.c:创建一个hello文件,之后对其上读取锁,键盘输入任意一个字符后解除读取锁。
/* read_lock.c */
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "lock_set.c"
int main(void)
{
	int fd;
	fd = open("hello",O_RDWR | O_CREAT, 0644);
	if(fd < 0)
	{
		printf("Open file error\n");
		exit(1);
	}
	/* 给文件上读取锁 */
	lock_set(fd,F_RDLCK);
	getchar();	//输入任意字符
	/* 给文件解锁 */
	lock_set(fd,F_UNLCK);
	getchar();	//输入任意字符
	close(fd);
	exit(0);
}

实现效果:
在这里插入图片描述

5. 在两个终端上运行./read_lock,查看运行结果。

在这里插入图片描述在这里插入图片描述

6. 验证: 如果在一个终端上运行读取锁程序,在另一个终端上运行写入锁程序,会有什么结果?

在这里插入图片描述
在这里插入图片描述

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值