概述
在文件已经共享的情况下,当多个用户共同使用时,如何对文件进行访问呢?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 %dn", lock.l_pid) ;
}
else if (lock.l_pid = F_WRLCK)//文件有写锁了
{
printf("Wirte lock aleady set by %dn", lock.l_pid) ;
}
}
lock.l_type = type ;//此时肯能已经被F_GETLK修改过
/*进行阻塞式上锁,F_SETLKW是F_SETLK的阻塞版本,如果没有获取到锁
就会进入睡眠状态,如果可以获取到锁或者捕捉到信号就会返回*/
if ((fcntl(fd, F_SETLKW, &lock)))
{
printf("lock failed:type = %dn", lock.l_type) ;
return 1 ;
}
switch(lock.l_type)
{
case F_RDLCK:
{
printf("read lock set by %dn", getpid()) ;
}
break ;
case F_WRLCK:
{
printf("write lock set by %dn", getpid()) ;
}
break ;
case F_UNLCK:
{
printf("release lock set by %dn", 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 errorn") ;
exit(1) ;
}
lock_set(fd, F_WRLCK) ;//给文件加上写入锁
getchar() ;//从终端获取一个输入字符
lock_set(fd, F_UNLCK) ;//给文件解锁
getchar() ;
close(fd) ;
exit(0) ;
}
终端1:
终端2:
等终端1解锁之后
终端1:
终端2:
可以看出写锁不是共享的,只能有一个 进程添加写锁
同样的原理试验读锁,发现读锁是可以共享的
在一个终端加入读锁,在另一个终端加入写锁也是不行的。
最后
以上就是单纯抽屉为你收集整理的文件锁的全部内容,希望文章能够帮你解决文件锁所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复