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

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
#include
#include
#include
#include
#include
#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);
}

补充笔记:关于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 , excute0755->即用户具有读/写/执行权限,组用户和其它用户具有读写权限;
0644->即用户具有读写权限,组用户和其它用户具有只读权限;
3. 在两个终端上运行./write_lock,查看运行结果


4. 编写文件读取锁的测试用例read_lock.c:创建一个hello文件,之后对其上读取锁,键盘输入任意一个字符后解除读取锁。
/* read_lock.c */
#include
#include
#include
#include
#include
#include
#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. 验证: 如果在一个终端上运行读取锁程序,在另一个终端上运行写入锁程序,会有什么结果?


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
