C语言文件与目录(五)文件锁

来源:转载


C语言文件与目录(五)文件锁,有需要的朋友可以参考下。


1)文件锁定

所谓的文件锁定,指的是以独占的方式打开文件。一个程序打开文件以后,其它的程序不能读取或写入文件。文件锁定有利于文件内容的一致性。本节将讲解文件的锁定权限问题。

文件锁定的理解:当多个程序程序同一个文件时,可能导致文件的内容不一致情况。例如一个文件中的数据是一个账户金额。用户打开这个文件读取数据,进行处理以后将写结果写入到文件。如果文件没有进行锁定时,可以发生下面这种错误。
(1)假设置文件中的数据为10000。用户A打开文件读取这个数据,读取了这个数据。但是还没有及时的写入。
(2)这时,用户B读取这个数据,将结果加10000。然后将结果20000写入到这个文件。
(3)用户A的处理时间较长,比用户B早读入数据,但后写入数据。A将数据加1000,得到11000,然后将数据写入到文件。
这时就发生了一个错误,用户B的数据丢失。这时需要在打开文件时进行文件锁定,正确的做法如下所示。
(1)假设置文件中的数据为10000。用户A打开文件读取这个数据,读取了这个数据。但是还不能及时的写入,于是将文件加一把锁,不允许别的用户访问。
(2)用户B访问这个文件时,文件已经加锁,无法访问。于是等待用户A完成数据访问。
(3)用户A完成数据处理以后,将信息写入到文件,这时解除对文件的锁定。
(4)这时用户B可以对文件进行访问。访问的同时,对文件添加一个锁定。在解除锁定以前,其他的用户不能访问这个文件。

文件锁定函数flock:在访问一个文件时,可以用flock函数对文件进行锁定。防止其他用户同时访问这个文件发生数据不一致的情况。这个函数的使用方法如下所示。
int flock(int fd,int operation);
在参数列表中,fd是open函数打开文件时返回的打开序号。operation是系统定义的一些整型常量,可能的取值和含义如下所示。
LOCK_SH:建立共享锁定,其他的程序可以同时访问这一个文件。多个程序可同时对同一个文件作共享锁定。
LOCK_EX:建立互斥锁定,其他用户不能同时访问这一个文件。
注意:一个文件同时只有一个互斥锁定。单一文件不能同时建立共享锁定与互斥锁定。
LOCK_UN:解除文件锁定状态。
LOCK_NB:无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。
当文件锁定成功时,会返回0,否则返回-1。可以用errno来捕获发生的错误。这个函数可能发生的错误如下所示。
EBADF:fd参数不是一个已经打开的文件。
EINTR:在进行操作时,这个操作被其他的程序或信号所中断。
EINVAL:给入的参数不合法。
ENOLCK:核心内存溢出错误。
EWOULDBLOCK:这个已经被其他程序建立互斥锁定。

DEMO:

int fd_lock;char file_lock[255]="";strcat(strcpy(file_lock,mainpath),"//file_lock.txt");if((fd_lock=open(file_lock,O_RDONLY))!=0){ if(flock(fd_lock,LOCK_EX)==0) { printf("%s %s/n",file_lock,"locked!"); } else { printf("%s/n",strerror(errno)); } close(fd_lock);}

2)文件某一部分锁定

文件锁定函数fcntl:函数fcntl的作用是对一个文件进行锁定。与flock函数不同的是,fcntl可以设定对文件的某一部分进行锁定。
该函数的使用方法如下所示。
int fcntl(int fd , int cmd);
int fcntl(int fd,int cmd,long arg);
int fcntl(int fd,int cmd,struct flock *lock);
这个函数的参数列表有多种形式。在编译时,会自动与参数进行匹配。参数fd是open函数打开文件时返回的文件编号。cmd是系统定义的一些整型常量,用来设置文件的打开方式,有下面几种可选方式。
F_DUPFD:用来查找大于或等于参数arg的最小且仍未使用的文件编号,并且复制参数fd的文件编号。执行成功则返回新复制的文件编号。
F_GETFD:取得close-on-exec标志。若此标志的参数arg 的FD_CLOEXEC位为0,代表在调用exec()相关函数时文件将不会关闭。
F_SETFD:设置close-on-exec 旗标。该旗标以参数arg的FD_CLOEXEC位决定。
F_GETFL:取得文件描述词状态旗标,此旗标为open的参数返回序号。
F_SETFL: 设置文件描述词状态旗标,参数arg为新旗标,但只允许O_APPEND、O_NONBLOCK和O_ASYNC位的改变,其他位的改变将不受影响。
F_GETLK:取得文件锁定的状态。
F_SETLK:设置文件锁定的状态。此时flcok 结构的l_type 值必须是F_RDLCK、F_WRLCK或F_UNLCK。如果无法建立锁定,则返回-1,错误代码为EACCES 或EAGAIN。
F_SETLKW或F_SETLK :这两个参数的作用相同,但是无法建立锁定时,此调用会一直等到锁定动作成功为止。
参数lock指针为flock类型的结构体指针,用来设置锁定文件的一个区域。flock结构体的定义方式如下所示。
01 struct flock
02 {
03 short int l_type;/*文件的锁定状态。*/
04 short int l_whence;/*设定l_start位置。*/
05 off_t l_start;/*锁定区域的开头位置,从这个地方开始锁定文件的内容。*/
06 off_t l_len;/*锁定文件区域的大小。*/
07 pid_t l_pid;/*锁定文件的进程。*/
08 };

l_type 有下面三种可选的参数。
F_RDLCK:建立一个供读取用的锁定。
F_WRLCK:建立一个供写入用的锁定。
F_UNLCK:删除之前建立的锁定方式。
l_whence 有下面的三种可选设置方式。
SEEK_SET:以文件开头为锁定的起始位置。
SEEK_CUR:以文件当前的读写位置为锁定的起始位置。
SEEK_END:以文件结尾为锁定的起始位置。
fcntl函数执行成功则返回0,失败则返回-1。这个函数可能发生下面的错误,可以用errno来捕获发生的错误。
EACCES或EAGAIN:文件已经被锁定,没有权限再进行锁定操作。
EAGAIN:文件已经被另外一个进程占用。
EBADF:df参数无效或文件已经关闭。
EDEADLK:这个文件被死锁。
EFAULT:文件处于只读的分区内。
EINTR:操作被其他的程序或信号中断。
EINVAL:函数所给的参数不合法。
EMFILE:已经超过了最多可以打开的文件数。
ENOLCK:已经建立了太多的锁定方式。
EPERM:在以追加方式打开的文件上错误的进行锁定。
在使用这个函数时,需要在程序的最前面包含下面的头文件。
#include <unistd.h>
#include <fcntl.h>

版权声明:本文为博主原创文章,未经博主允许不得转载。



分享给朋友:
您可能感兴趣的文章:
随机阅读: