fcntl函数的说明与实例 (文件加锁)
对文件加锁是原子性的,可以用于进程间文件操作的同步。在linux下,有三个函数可以对文件进程加锁,分别是fcntl、flock、lockf。这里只说fcntl,它的用法也是最复杂的。
fcntl是file control的缩写。在linux下大部分设备都是文件,所以fcntl的功能也比较多,包括:
•Duplicating a file descriptor(复制文件描述符)
•File descriptor flags(操作close-on-exec标志)
•File status flags(操作文件O_RDONLY , O_WRONLY , O_RDWR , O_APPEND , O_NONBLOCK , O_SYNC和O_ASYNC标识)
•Advisory locking(建议性锁)
•Mandatory locking(强制性锁)
•Managing signals(管理信号)
•Leases(租借锁)
•File and directory change notification (dnotify)(文件和目录更改消息)
•Changing the capacity of a pipe(改变管道大小)
这里只说一下Advisory locking和Mandatory locking。建议性锁是指给文件上锁后,只在文件上设置了一个锁的标识。其他进程在对这个文件进程操作时,可以检测到锁的存在,但这个锁并不能阻止它对这个文件进行操作。这就好比红绿灯,当亮红灯时,告诉你不要过马路,但如果你一定要过,也拦不住你。强制性锁则是当给文件上锁后,当其他进程要对这个文件进程不兼容的操作(如上了读锁,另一个进程要写),则系统内核将阻塞后来的进程直到第一个进程将锁解开。在该功能下,fcntl的函数原型为:
复制代码代码如下:
#include unistd.h
#include fcntl.h/p
int fcntl(int fd, int cmd,struct flock plock );
struct flock {
...
short l_type;/ Type of lock: F_RDLCK,
F_WRLCK, F_UNLCK /
short l_whence;/ How to interpret l_start:
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) */
...
};
Advisory locking共有三个操作,分别是F_GETLK、F_SETLK、F_SETLKW。其中F_GETLK用来测试锁,注意是测试而不是获取锁;F_SETLK用来加锁、解锁;F_SETLKW功能同F_SETLK,只是操作变成阻塞式的。而fcntl可以用过l_whence、l_start、l_len来控制文件上锁的区间。下面分别是上锁、测试锁的代码。
复制代码代码如下:
/slock.c//p
#include
#include
#include
#include
int main()
{
struct flock _lock;
_lock.l_type =F_WRLCK;
_lock.l_whence = SEEK_SET;
_lock.l_start = 0;
_lock.l_len = 0;
int fd = open( "/dev/shm/test",O_CREAT|O_RDWR,S_IRWXU|S_IRGRP|S_IWGRP|S_IRWXO );
if ( fd {
puts( "open error" );
return 0;
}
int ret = fcntl( fd,F_SETLK,&_lock );
if ( ret {
puts( "fcntl error" );
close( fd );
return 0;
}
puts( "sleep now ..." );
sleep( 100 );
puts( "exit..." );
_lock.l_type =F_UNLCK;
_lock.l_whence = SEEK_SET;
_lock.l_start = 0;
_lock.l_len = 0;
ret = fcntl( fd,F_SETLK,&_lock );
if ( ret {
puts( "unlock error" );
}
close( fd );
}
复制代码代码如下:
/glock.c //p
#include
#include
#include
#include
#include
int main()
{
struct flock _lock;
_lock.l_type =F_RDLCK;
_lock.l_whence = SEEK_SET;
_lock.l_start = 0;
_lock.l_len = 0;
int fd = open( "/dev/shm/test",O_RDWR );
if ( fd {
perror( "open error" );
return 0;
}
int ret = fcntl( fd,F_GETLK,&_lock );
if ( ret {
perror( "fcntl error:" );
close( fd );
return 0;
}
printf( "lock is %d",_lock.l_type );
close( fd );
}
在上面的代码中,"_lock.l_type = F_RDLCK;"表示给文件上读共享锁,"_lock.l_whence = SEEK_SET;"表示从文件开头开始加锁,"_lock.l_start = 0;"表示偏移l_whence多少字节开始加锁,"_lock.l_len = 0;"表示加锁的字节数,即长度(Specifying 0 for l_len has the special meaning: lock all bytes starting at the location specified by l_whence and l_start through to the end of file, no matter how large the file grows.)。
在上面的代码中,分别编译为slock、glock。先运行slock再运行glock:
复制代码代码如下:
./slock
sleep now ...
./glock
lock is 1
exit...
slock先给文件上写锁,然后glock测试读共享锁是否能加上,测试结果是已存在一个写锁(F_WRLCK,debian下定义为1)。这里需要注意的是F_GETLK是测试锁是否能加上,如果可以,则struct flock中的l_type为F_UNLCK;如果不行,则l_type为文件当前锁的类型,而l_pid为上锁的进程pid。故如果slock上的锁是F_RDLCK,glock测试的锁也是F_RDLCK,这两个锁是兼容的,返回的l_type类型为F_UNLCK。即你不能通过F_GETLK来判断文件是否上锁,只能测试某个锁是否能加上。
上面的是建议性锁,如果要实现强制性锁,则:
复制代码代码如下:
Tomake use of mandatory locks, mandatory locking must be enabled both on the filesystem that contains the file to be locked, and on thefile itself. Mandatorylockingisenabled on a filesystem using the "-o
mand" option to mount(8), or the MS_MANDLOCK flag for mount(2). Mandatory locking is enabled on a file by disabling group execute permission
on the file and enabling the set-group-ID permission bit (seechmod(1) and chmod(2)).
这是说,要实现强制性锁则须将文件所在的文件系统用"-o mand"参数来挂载,并且使用chmod函数将文件用户组的x权限去掉。然后用上面同样的代码就可以了。我第一次见这么奇特的函数,实现一个功能并不是通过本身的参数控制,而是系统设置.....幸好我也不用强制性锁。
以上是fcntl加文件锁的简单例子。需要注意的是不同系统的实现并不一样,宏定义也不一样。如:
http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/fcntl.h
#define F_RDLCK 1
#define F_UNLCK 2
#define F_WRLCK 3
而在debian中,/usr/include/bits/fcntl.h
#define F_RDLCK 0
#define F_WRLCK 1
#define F_UNLCK 2
推荐系统
雨林木风 winxp下载 纯净版 永久激活 winxp ghost系统 sp3 系统下载
系统大小:0MB系统类型:WinXP雨林木风在系统方面技术积累雄厚深耕多年,打造了国内重装系统行业知名品牌,雨林木风WindowsXP其系统口碑得到许多人认可,积累了广大的用户群体,是一款稳定流畅的系统,雨林木风 winxp下载 纯净版 永久激活 winxp ghost系统 sp3 系统下载,有需要的朋友速度下载吧。
系统等级:进入下载 >萝卜家园win7纯净版 ghost系统下载 x64 联想电脑专用
系统大小:0MB系统类型:Win7萝卜家园win7纯净版是款非常纯净的win7系统,此版本优化更新了大量的驱动,帮助用户们进行舒适的使用,更加的适合家庭办公的使用,方便用户,有需要的用户们快来下载安装吧。
系统等级:进入下载 >雨林木风xp系统 xp系统纯净版 winXP ghost xp sp3 纯净版系统下载
系统大小:1.01GB系统类型:WinXP雨林木风xp系统 xp系统纯净版 winXP ghost xp sp3 纯净版系统下载,雨林木风WinXP系统技术积累雄厚深耕多年,采用了新的系统功能和硬件驱动,可以更好的发挥系统的性能,优化了系统、驱动对硬件的加速,加固了系统安全策略,运行环境安全可靠稳定。
系统等级:进入下载 >萝卜家园win10企业版 免激活密钥 激活工具 V2023 X64位系统下载
系统大小:0MB系统类型:Win10萝卜家园在系统方面技术积累雄厚深耕多年,打造了国内重装系统行业的萝卜家园品牌,(win10企业版,win10 ghost,win10镜像),萝卜家园win10企业版 免激活密钥 激活工具 ghost镜像 X64位系统下载,其系统口碑得到许多人认可,积累了广大的用户群体,萝卜家园win10纯净版是一款稳定流畅的系统,一直以来都以用户为中心,是由萝卜家园win10团队推出的萝卜家园
系统等级:进入下载 >萝卜家园windows10游戏版 win10游戏专业版 V2023 X64位系统下载
系统大小:0MB系统类型:Win10萝卜家园windows10游戏版 win10游戏专业版 ghost X64位 系统下载,萝卜家园在系统方面技术积累雄厚深耕多年,打造了国内重装系统行业的萝卜家园品牌,其系统口碑得到许多人认可,积累了广大的用户群体,萝卜家园win10纯净版是一款稳定流畅的系统,一直以来都以用户为中心,是由萝卜家园win10团队推出的萝卜家园win10国内镜像版,基于国内用户的习惯,做
系统等级:进入下载 >windows11下载 萝卜家园win11专业版 X64位 V2023官网下载
系统大小:0MB系统类型:Win11萝卜家园在系统方面技术积累雄厚深耕多年,windows11下载 萝卜家园win11专业版 X64位 官网正式版可以更好的发挥系统的性能,优化了系统、驱动对硬件的加速,使得软件在WINDOWS11系统中运行得更加流畅,加固了系统安全策略,WINDOWS11系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。
系统等级:进入下载 >
相关文章
- 老电脑装Win7还是Win10-适合老电脑安装的系统介绍
- Gpu不工作的解决方法
- 电脑连接打印机提示0X00000709错误代码三种解决方法分享
- 笔记本电脑怎么强制关机-笔记本电脑强制关机的方法
- Dll文件存在仍显示找不到怎么办
- 电脑无法启动或仍在加载怎么办
- 打印机连接操作失败提示0x0000011b怎么办?
- 电脑网络适配器出现黄色感叹号怎么办?网络适配器下面全是黄色感叹号的接解决方法
- 系统32位和62位怎么选择:详解它们之间的差异
- 显卡驱动版本过低怎么升级-最全的升级显卡驱动方法
- 电脑C盘无法扩展怎么办-C盘无法扩展的解决方法
- 文件删除不了需要管理员权限怎么办-需要管理员权限的解决方法
- CMD怎么以管理员身份运行-以管理员身份运行CMD的三种方法
- 截图快捷键不能用了怎么办-截图快捷键不能用了的解决方法
热门系统
推荐软件
推荐应用
推荐游戏
热门文章
常用系统
- 1番茄花园win10 ghost系统下载 自动激活 v2022.05 下载
- 2Windows11系统下载 番茄花园 win11旗舰版 ghost镜像 ISO X64位
- 3系统之家Win10纯净专业版镜像
- 4【巅峰性能,为专业而生】Windows10 22H2 64位 专业工作站版
- 5win11怎么升级?萝卜家园Win11系统一键安装 64位 windows家庭版 V2022.01
- 6系统之家Windows7 64位最新纯净版
- 7番茄花园win10企业版下载 自动激活 无需win10企业版激活码 win10永久激活
- 8深度系统Win11专业版 永久激活 Win11 ghost ISO X64位系统下载
- 9系统之家WinXP专业版 32位镜像下载 笔记本专用 x86最新版下载