Linux系统编程--fcntl()读写锁实例

在多进程对同一个文件进行读写访问时,为了保证数据的完整性,有事需要对文件进行锁定。可以通过fcntl()函数对文件进行锁定和解锁。
1. fcntl
1.1.功能描述:根据文件描述词来操作文件的特性。
1.2.用法:
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
fd:文件描述词。
cmd:操作命令。
arg:供命令使用的参数,是否需要arg参数跟cmd命令有关。
lock:锁信息。
2.读写锁实例
新建两个文件,源码如下2.1、2.2所示。
2.1.给文件加读锁
#include
#include
#include
#include
#include
int main(int argc, const char * argv [ ])
{
int fd = open(test.c, o_rdonly);
if (fd == -1)
{
perror(open failed:);
return -1;
}
struct stat sta;
fstat(fd,&sta);
struct flock lock;
lock.l_len = sta.st_size;
lock.l_pid = getpid();
lock.l_start = 0;
lock.l_type = f_rdlck;
lock.l_whence = seek_set;
printf(进程pid: %d,lock.l_pid);
if(fcntl(fd,f_setlk,&lock) == -1)
{
perror(fcntl fail );
return -1;
}
else
{
printf(add read lock success!);
}
sleep(10);
close(fd);
return 0;
}
2.2.给文件加写锁
#include
#include
#include
#include
#include
int main(int argc, const char * argv [ ])
{
int fd = open(test.c, o_wronly);
if (fd == -1)
{
perror(open failed:);
return -1;
}
struct stat sta;
fstat(fd,&sta);
struct flock lock;
lock.l_len = sta.st_size;
lock.l_pid = getpid();
lock.l_start = 0;
lock.l_type = f_wrlck;
lock.l_whence = seek_set;
printf(进程pid: %d,lock.l_pid);
while(fcntl(fd,f_setlk,&lock) == -1 )
{
perror(fcntl:);
sleep(1);
struct flock lock_1;
lock_1 = lock;
lock_1.l_type = f_wrlck; //
fcntl(fd,f_getlk,&lock_1);//获取文件锁状态,及加锁(lock_1.l_type)能否成功
switch(lock_1.l_type)
{
case f_rdlck:
printf(检测到读锁 pid = %d ,lock_1.l_pid);
break;
case f_wrlck:
printf(检测到写锁 pid = %d ,lock_1.l_pid);
break;
case f_unlck:
printf(检测到已解锁.pid = %d ,lock_1.l_pid);
}
}
printf(写锁设置成功);
getchar();
close(fd);
return 0;
}
/*
注意:
1、fcntl(fd,f_getlk,&lock_1)中的lock_1必须进行初始化,并且lock_1.l_type必须设置为相应的锁,才能确定能否加锁成功,及不成功的原因。
2、getlk时,fcntl先检测有没有能阻止本次加锁的锁,如果有,则覆盖flock结构体(lock_1)的信息。如果没有,则置lock_1.l_type 的类型为f_unlck。
*/
对于写锁(f_wrlck 独占锁),只有一个进程可以在文件的任一特定区域上享有独占锁。
对于读锁(f_rdlck 共享锁),许多不同的进程可以同时拥有文件上同一区域上的共享锁。为了拥有共享锁,文件必须以读或者读/写的方式打开。只要任一进程拥有共享锁,那么其他进程就无法再获得独占锁。
分别编译执行:
3.先执行读锁,再执行写锁。结果如下:
liu@ubuntu:~/learn/lrn_linux$ ./readlock.out
进程pid: 16458
add read lock success!
liu@ubuntu:~/learn/lrn_linux$ ./writelock.out
进程pid: 16459
fcntl:: resource temporarily unavailable
检测到读锁 pid = 16458
fcntl:: resource temporarily unavailable
检测到读锁 pid = 16458
fcntl:: resource temporarily unavailable
检测到读锁 pid = 16458
fcntl:: resource temporarily unavailable
检测到读锁 pid = 16458
fcntl:: resource temporarily unavailable
检测到读锁 pid = 16458
fcntl:: resource temporarily unavailable
检测到读锁 pid = 16458
fcntl:: resource temporarily unavailable
检测到读锁 pid = 16458
fcntl:: resource temporarily unavailable
检测到已解锁.pid = 16459
写锁设置成功
可以看出,当文件被读锁占用时,无法添加写锁(独占锁)
4.先运行写锁,再运行读锁的话,结果如下:
liu@ubuntu:~/learn/lrn_linux$ ./writelock.out
进程pid: 16349
写锁设置成功
liu@ubuntu:~/learn/lrn_linux$ ./readlock.out
进程pid: 16350
fcntl fail : resource temporarily unavailable
所以,加锁是成功的。

一加刘作虎:今年力争做到影像功能全球第一
激光位移传感器有机器人控制上的应用
模拟电子技术难吗 10个经典模拟电路带你搞懂
抢先攻占IC制造商机 联电发力14纳米制程技术
采集数据慢,有报错维修吉时利源表2636B
Linux系统编程--fcntl()读写锁实例
TP-Link11正式发布了自己的第一款802.11ax Wi-Fi路由器
解析丰田L4级自动驾驶计算平台
电子设备智能供应链协同解决方案: 赋能产业数字化升级
压注法封装贴片LED填补空白 达到国际领先水平
仪器租赁助力企业轻松应对经济危机
协作是物联网创新的关键
有奖邀约视频号“知识推荐官”,领取您的圣诞好礼~
车载电子设备不可或缺的EMC/EMI
“荣耀智慧屏“不是电视,是电视的未来”
Modbus RTU连接YGWE通讯点表单双机头
2018Q2全球市场手机均价及涨幅,哪些手机品牌涨价最猛?
中国高铁和谐号问世全面实现中国制造业智能化的中心思想
怎样用废微波炉建造一个小型电风扇
三星或将于第三季度推出铰接式可折叠手机