您的位置:首页 > 编程语言 > C语言/C++

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

2015-11-06 14:17 417 查看

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: