文件锁:包括共享文件锁,独占文件锁
实现函数为:
int fcntl(int fd,int cmd,struct flock *lock);
fd 为文件描述符,cmd为命令参数,flock结构体用来记录锁的属性
cmd 可取如下几个值:
F_GETLK 根据lock参数值,决定是否上文件锁
F_SETLK 设置lock参数值的文件锁
F_SETLKW 这是 F_GETLK的阻塞版本,在无法获取锁时,会进入睡眠状态。flock 结构体:
-
struct flock {
short l_type;
off_t l_start;
short l_whence;
off_t l_len;
pid_t l_pid;
}
l_type 表示锁的类型,可取:F_RDLCK(共享锁,用于只读),F_WRLCK(独占锁,用于写) F_UNLCK(解除锁)
l_whence 区:SEEK_SET,SEEK_CUR,SEEK_END三个值
l_start : 相对于l_whence 的偏移
l_len: 锁定文件的长度
l_pid : 当前文件操作的进程id号
测试代码:
-
struct flock {
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
/*
文件锁测试代码
*/
const char* path="/home/wyz19891024/code/ccode/flock.txt";
int main()
{
int fd;
int i = 0;
struct flock region_lock;
char ch = 'A';
int ret;
fd = open(path,O_CREAT | O_RDWR,0666);
if(fd < 0)
{
fprintf(stderr,"open file:%s failed\n",path);
return 1;
}
fprintf(stdout,"write data to file\n");
while(i < 21) //向文件中写数据
{
write(fd,&ch,sizeof(ch));
i++;
}
region_lock.l_type = F_RDLCK;
region_lock.l_whence = SEEK_SET; //文件5-10字节设置共享锁
region_lock.l_start = 5;
region_lock.l_len = 5;
fprintf(stdout,"process:%d set F_RDLCK from %d to %d\n",getpid(),5,10);
ret = fcntl(fd,F_SETLK,®ion_lock);
region_lock.l_type = F_WRLCK; //独占锁
region_lock.l_whence = SEEK_SET;
region_lock.l_start = 15;
region_lock.l_len = 5;
fprintf(stdout,"process:%d set F_WRLCK from %d to %d\n",getpid(),15,20);
ret = fcntl(fd,F_SETLK,®ion_lock);
sleep(60);
close(fd);
return 0;
}
/××××××××××××××××××××××××××××/
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
const char* path = "/home/wyz19891024/code/ccode/flock.txt";
const char* str = "hello";
int main()
{
int fd;
struct flock region_lock;
char buf[10];
fd = open(path,O_CREAT | O_RDWR,0666);
lseek(fd,5,SEEK_SET);
fprintf(stdout,"process % ,try to read file from %d to %d\n",getpid(),5,10);
memset(buf,'\0',sizeof(buf));
if(read(fd,buf,5) == -1)
{
fprintf(stderr,"read from %d to %d \n failed\n",5,10);
return 1;
}
fprintf(stdout,"read data:%s\n",buf);
lseek(fd,5,SEEK_SET);
fprintf(stdout,"try to write file from %d to %d \n",5,10);
if(write(fd,str,5) == -1)
{
fprintf(stderr,"write data %s failed\n",str);
return 1;
}
else
{
fprintf(stdout,"write data %s success!\n",str);
}
lseek(fd,15,SEEK_SET);
fprintf(stdout,"try to read data from %d to %d\n",15,20);
memset(buf,'\0',sizeof(buf));
if(read(fd,buf,5) == -1)
{
fprintf(stderr,"read data from %d to %d failed\n",15,20);
return 1;
}
return 0;
}
更加详细见:http://blog.chinaunix.net/uid-23634108-id-2393492.html