本文主要是介绍fcntl(文件锁),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
fcntl(文件锁)
表头文件 #include <unistd.h>
#include <fcntl.h>
函数定义 int fcntl(int fd, int cmd, struct flock *lock);
函数说明 fd:文件描述符
设置的文件描述符,参数cmd代表欲操作的指令
F_DUPFD
复制参数fd的文件描述符,执行成功则返回新复制的文件描述符,
F_GETFD
取得close-on-exec标志,若些标志的FD_CLOEXEC位为0,代表在调用
exec()相关函数时文件将不会关闭
F_SETFD 设置close-on-exec标志,该标志以参数arg的 FD_CLOEXEC位决定
F_GETFL 得到open()设置的标志
F_SETFL 改变open()设置的标志
F_GETLK 取得文件锁定的状态,根据lock的描述,决定是否上文件锁
F_SETLK 设置文件锁定的状态,此时flcok,结构的l_tpye值必须是F_RDLCK、F_WRLCK或F_UNLCK,
如果无法建立锁定,则返回-1
F_SETLKW 是F_SETLK的阻塞版本,在无法获取锁时会进入睡眠状态,如果可以获取锁或者捕获到信号则返回
参数lock指针为flock结构指针定义如下
struct flock {
...
short l_type; /* Type of lock: F_RDLCK,锁定的状态
F_WRLCK, F_UNLCK */
short l_whence; /* How to interpret l_start:决定l_statr位置
SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Starting offset for lock */锁定区域的开关位置
off_t l_len; /* Number of bytes to lock */锁定区域的大小
pid_t l_pid; /* PID of process blocking our lock
(F_GETLK only) */锁定动作的进程
...
};
1_type有三种状态:
F_RDLCK读取锁(共享锁)
F_WRLCK写入锁(排斥锁)
F_UNLCK解锁
l_whence也有三种方式
SEEK_SET以文件开头为锁定的起始位置
SEEK_CUR以目前文件读写位置为锁定的起始位置
SEEK_END以文件尾为锁定的起始位置
返回值 成功则返回0,若有错误则返回-1
l_len:加锁区的长度
l_pid:具有阻塞当前进程的锁,其持有进程的进程号存放在l_pid中,由F_GETLK返回
通常是将l_start设置为0,l_whence设置为SEEK_SET,l_len设置为0
---------------------------------------------------------------------------------------------
lock_set.c
----------------------------------------------------------------------------------------------
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
int lock_set(int fd,int type)
{
struct flock lock;
lock.l_whence=SEEK_SET;
lock.l_start=0;
lock.l_len=0;
lock.l_type=type;
lock.l_pid=-1;
fcntl(fd,F_GETLK,&lock);//get the fd and lock status
if(lock.l_type!=F_UNLCK)
{
if(lock.l_type==F_RDLCK)
{
printf("Read lock already set by %d/n",lock.l_pid);
}
else if(lock.l_type==F_WRLCK)
{
printf("Write lock already set by %d/n",lock.l_pid);
}
}
lock.l_type=type;//F_GETLK maybe chmod the lock.l_type type
if(fcntl(fd,F_SETLKW,&lock)<0)//set 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 by %d/n",getpid());
}
break;
default:
break;
}
return 0;
}
--------------------------------------------------------------------------------------------
test_write_read_lock.c
-------------------------------------------------------------------------------------------
#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"
char buf[]="shui xian bin you are best!";
char s[100]="";
int main(void)
{
int fd;
fd=open("t.txt",O_RDWR|O_CREAT|O_APPEND,0777);
if(fd<0)
{
perror("open");
exit(1);
}
lock_set(fd,F_WRLCK);
write(fd,buf,sizeof(buf));
lock_set(fd,F_UNLCK);
close(fd);
fd=open("t.txt",O_RDWR,0777);
if(fd<0)
{
perror("open");
exit(1);
}
lock_set(fd,F_RDLCK);
read(fd,s,sizeof(s));
lock_set(fd,F_UNLCK);
printf("read ...%s/n",s);
close(fd);
exit(0);
}
----------------------------------------------------------------------------------------
[root@localhost test]# ./s
Write lock set by 6224
Release lock by 6224
Read lock set by 6224
Release lock by 6224
read ...shui xian bin you are best!
-----------------------------------------------------------------------------------------
这篇关于fcntl(文件锁)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!