文件锁
来源:互联网 发布:centos开mc服务器 编辑:程序博客网 时间:2024/05/18 17:59
在文件已经共享的情况下,当多个用户共同使用时,如何对文件进行访问呢?linux采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。锁分为建议锁和强制锁
建议锁:要求每个上锁文件的进程都要检查是否有锁存在,并尊重已有的锁,一般情况下内核和系统都不使用建议性锁。
强制锁:由内核执行的锁,当一个文件被上锁进行写入的时候,内核将阻止其他任何文件对其进行读写操作,采用强制性锁对性能影响很大,每次读写都必须检查是否有锁存在。
上锁主要有两个函数:lockf()--------对文件施加建议性锁
fcntl()--------可以施加建议性锁和强制性锁,并且可以施加建议性锁
记录锁分为读取锁和写入锁,读取锁是共享的,但写入锁是互斥的,也就是同一时刻只能有一个进程在文件的某个部分添加写入锁,当然文件不能同时加入写入锁和读取锁
ps:fcntl()不仅可以管理文件锁,而且可以获得和设置文件描述符和文件描述符标志,文件描述符的复制等功能,下面就是如何添加记录锁
fcntl()函数语法:
lock结构体的定义:
struct flock{ shrot l_type ; off_t l_shart ; short l_whence ; off_t l_len ; pid_t l_pid ;}
lock结构中每个变量含义如下
ps:为了加锁整个文件通常的做法是将l_start设置为0,l_whenec设置为seek_set,l_len设置为0
这里有个使用文件记录锁得例子
文件记录锁的代码:
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 ; /*F_GETLK判断文件是否能根据lock中的描述上锁,如果可以上锁则将flock结构中的l_type设置成F_UNLCK,如果 不能上锁l_pid设置成拥有文件锁得进程号,其他的不变*/ fcntl(fd, F_GETLK, &lock) ; if (lock.l_type != F_UNLCK)//判断文件不能上锁的原因 { if (lock.l_type == F_RDLCK)//文件有读锁了 { printf("read lock aleady set by %d\n", lock.l_pid) ; } else if (lock.l_pid = F_WRLCK)//文件有写锁了 { printf("Wirte lock aleady set by %d\n", lock.l_pid) ; } } lock.l_type = type ;//此时肯能已经被F_GETLK修改过 /*进行阻塞式上锁,F_SETLKW是F_SETLK的阻塞版本,如果没有获取到锁 就会进入睡眠状态,如果可以获取到锁或者捕捉到信号就会返回*/ if ((fcntl(fd, F_SETLKW, &lock))) { 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 set by %d\n", getpid()) ; } break ; default: break ; } return 0 ;}
下面是测试实例,先加入写入锁,最后再释放锁得过程。可以打开两个终端进行测试
#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(){ int fd ; fd = open("hello", O_RDWR| O_CREAT, 0644) ; if (fd < 0) { printf("open file error\n") ; exit(1) ; } lock_set(fd, F_WRLCK) ;//给文件加上写入锁 getchar() ;//从终端获取一个输入字符 lock_set(fd, F_UNLCK) ;//给文件解锁 getchar() ; close(fd) ; exit(0) ;}
终端1:
终端2:
等终端1解锁之后
终端1:
终端2:
可以看出写锁不是共享的,只能有一个 进程添加写锁
同样的原理试验读锁,发现读锁是可以共享的
在一个终端加入读锁,在另一个终端加入写锁也是不行的。
- 文件操作-文件锁
- Linux文件---文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- 文件锁
- Web Services的起源和基本原理
- 【从测试数据看出你的密码是否安全】
- jquery事件对象属性
- Firebug入门指南
- 浏览器开发调试工具的秘密 - Secrets of the Browser Developer Tools
- 文件锁
- QQMusic与Android studio 冲突导致Adb not reposponding
- 内存管理 - 11.6 slab层
- Java 理论与实践: 正确使用 Volatile 变量
- pthread_cond_wait用法解析与案例
- 三步骤改电源设置 电脑降温有绝招
- 高新_枚举、反射、泛型、类加载器、动态代理
- FFMPEG CODEC使用总结(zz)
- 利用CURL工具诊断WEB页面访问性能