fcntl系统调用可以用来对已打开的文件描述符进行各种控制操作以改变已打开文件的的各种属性
函数原型:

#include<unistd.h>
#include<fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd ,struct flock* lock);

fcntl函数功能依据cmd的值的不同而不同。参数对应功能如下:

(1)F_DUPFD

与dup函数功能一样,复制由fd指向的文件描述符,调用成功后返回新的文件描述符,与旧的文件描述符共同指向同一个文件。

(2)F_GETFD

读取文件描述符close-on-exec标志

(3)F_SETFD

将文件描述符close-on-exec标志设置为第三个参数arg的最后一位

(4)F_GETFL

获取文件打开方式的标志,标志值含义与open调用一致

(5)F_SETF

设置文件打开方式为arg指定方式

//F_DUPFD,
#include<fcntl.h>
#include<unistd.h>
#include <stdio.h>
#include <string.h>int fcntl_cmd()
{int fd,dupfd,t;char *buff="123456\n";t=strlen(buff);fd=open("test.txt",O_RDWR|O_CREAT,0644);if(fd<0) return -1;dupfd=fcntl(fd,F_DUPFD,0);//相当于dupfd=dup(fd);if(dupfd<0) return -2;if(write(dupfd,buff,t)!=t) return -3;close(dupfd);
}
int main()
{int ret=fcntl_cmd();if(ret==-1)printf("open error \n");else if(ret== -2) printf("DUPFD error\n");else if(ret==-3)printf("write error \n");return 0;
}


文件记录锁是fcntl函数的主要功能。

记录锁:实现只锁文件的某个部分,并且可以灵活的选择是阻塞方式还是立刻返回方式

当fcntl用于管理文件记录锁的操作时,第三个参数指向一个struct flock *lock的结构体

struct flock
{short_l_type;    /*锁的类型*/short_l_whence;  /*偏移量的起始位置:SEEK_SET,SEEK_CUR,SEEK_END*/off_t_l_start;     /*加锁的起始偏移*/off_t_l_len;    /*上锁字节*/pid_t_l_pid;   /*锁的属主进程ID */
};

short_l_type用来指定设置共享锁(F_RDLCK,读锁)还是互斥锁(F_WDLCK,写锁).

当short_l_type的值为 F_UNLCK时,传入函数中将解锁
每个进程可以在该字节区域上设置不同的读锁。

但给定的字节上只能设置一把写锁,并且写锁存在就不能再设其他任何锁,且该写锁只能被一个进程单独使用。

这是多个进程的情况。

单个进程时,文件的一个区域上只能有一把锁,若该区域已经存在一个锁,再在该区域设置锁时,新锁会覆盖掉旧的锁,无论是写锁还时读锁。

l_whence,l_start,l_len三个变量来确定给文件上锁的区域

l_whence确定文件内部的位置指针从哪开始,l_star确定从l_whence开始的位置的偏移量,两个变量一起确定了文件内的位置指针先所指的位置,即开始上锁的位置,然后l_len的字节数就确定了上锁的区域。

特殊的,当l_len的值为0时,则表示锁的区域从起点开始直至最大的可能位置,就是从l_whence和l_start两个变量确定的开始位置开始上锁,将开始以后的所有区域都上锁。

为了锁整个文件,我们会把l_whence,l_start,l_len都设为0。

(6)F_SETLK

此时fcntl函数用来设置或释放锁。当short_l_type为F_RDLCK为读锁,F_WDLCK为写锁,F_UNLCK为解锁。

如果锁被其他进程占用,则返回-1;

这种情况设的锁遇到锁被其他进程占用时,会立刻停止进程。

(7)F_SETLKW

此时也是给文件上锁,不同于F_SETLK的是,该上锁是阻塞方式。当希望设置的锁因为其他锁而被阻止设置时,该命令会等待相冲突的锁被释放。

(8)F_GETLK

第3个参数lock指向一个希望设置的锁的属性结构,如果锁能被设置,该命令并不真的设置锁,而是只修改lock的l_type为F_UNLCK,然后返回该结构体。如果存在一个或多个锁与希望设置的锁相互冲突,则fcntl返回其中的一个锁的flock结构。
————————————————
版权声明:本文为CSDN博主「Rotation.」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fengxinlinux/article/details/51980837

以下代码用来证明写锁的互斥性

#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
/*lock_set函数*/
void lock_set(int fd, int type)
{struct flock lock;
lock.l_whence = SEEK_SET;//赋值lock结构体
lock.l_start = 0;
lock.l_len =0;
while(1){lock.l_type = type;
/*根据不同的type值给文件上锁或解锁*/
if((fcntl(fd, F_SETLK, &lock)) == 0){if( lock.l_type == F_RDLCK )
printf("read lock set by %d\n",getpid());
else if( lock.l_type == F_WRLCK )
printf("write lock set by %d\n",getpid());
else if( lock.l_type == F_UNLCK )
printf("release lock by %d\n",getpid());
return;
}
/*判断文件是否可以上锁*/
fcntl(fd, F_GETLK,&lock);
/*判断文件不能上锁的原因*/
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);
getchar();
}
}
}int main(void)
{int fd;
/*首先打开文件*/
fd=open("hello",O_RDWR | O_CREAT, 0666);
if(fd < 0){perror("open");
exit(1);
}
/*给文件上写入锁*/
lock_set(fd, F_WRLCK);
getchar();
/*给文件接锁*/
lock_set(fd, F_UNLCK);
getchar();
close(fd);
exit(0);
}

终端一:

[root@localhost file]# ./fcntl_write
write lock set by 4994
release lock by 4994

终端二:

[root@localhost file]# ./fcntl_write
write lock already set by 4994
write lock set by 4997
release lock by 4997

以下代码证明读取锁为共享锁

/*fcntl_read.c测试文件读取锁主函数部分*/
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{int fd;
fd=open("hello",O_RDWR | O_CREAT, 0666);
if(fd < 0){perror("open");
exit(1);
}
/*给文件上读取锁*/
lock_set(fd, F_RDLCK);
getchar();
/*给文件接锁*/
lock_set(fd, F_UNLCK);
getchar();
close(fd);
exit(0);
}

终端一:

[root@localhost file]# ./fcntl2
read lock set by 5009
release lock by 5009

终端二:

[root@localhost file]# ./fcntl2
read lock set by 5010
release lock by 5010

参考链接:https://www.jb51.net/article/37671.htm

fcntl的详细使用相关推荐

  1. 文件控制 fcntl函数具体解释

    摘要:本文主要讨论文件控制fcntl函数的基本应用.dup函数能够拷贝文件描写叙述符,而fcntl函数与dup函数有着异曲同工之妙.而且还有更加强大的功能,能够获取或设置已打开文件的性质,操作文件锁. ...

  2. Linux 系统 文件锁 fcntl函数详解

    #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); int fcntl(int fd, int ...

  3. sigaction 函数,sigemptyset()函数,fcntl()函数,isatty()函数

    第一个函数:使用 sigaction函数: signal 函数的使用方法简单,但并不属于POSIX标准,在各类UNIX平台上的实现不尽相同,因此其用途受 到了一定的限制.而 POSIX标准定义的信号处 ...

  4. 处理大并发之四 libevent demo详细分析(对比epoll)

    处理大并发之四 libevent demo详细分析(对比epoll) libevent默认情况下是单线程,每个线程有且仅有一个event_base,对应一个struct event_base结构体,以 ...

  5. Linux惊群效应详解(最详细的了吧)

    https://blog.csdn.net/lyztyycode/article/details/78648798?locationNum=6&fps=1 linux惊群效应 详细的介绍什么是 ...

  6. Linux文件(区域)锁函数 -- open()、fcntl()

    一.什么是文件锁定 对于锁这个字,大家一定不会陌生,因为我们生活中就存在着大量的锁,它们各个方面发挥着它的作用,现在世界中的锁的功能都可归结为一句话,就是阻止某些人做某些事,例如,门锁就是阻止除了屋主 ...

  7. 处理大并发之四 libevent demo详细分析(对比epoll)

    处理大并发之四 libevent demo详细分析(对比epoll) libevent默认情况下是单线程,每个线程有且仅有一个event_base,对应一个struct event_base结构体,以 ...

  8. 详细分析Apple macOS 6LowPAN 漏洞(CVE-2020-9967)

     聚焦源代码安全,网罗国内外最新资讯! 安全研究员 Alex Plaskett 在2020年5月向苹果报告了影响MacOS Big Sur 的一个漏洞 (CVE-2020-9967).苹果公司在12月 ...

  9. Android:通过systrace进行性能分析及使用-详细

    Android:通过systrace进行性能分析 https://www.cnblogs.com/blogs-of-lxl/p/10926824.html 一.Systrace 简介 Systrace ...

最新文章

  1. 网站制作基本要素了解一下
  2. base64 string 放不下_String、byte[]、Base64相互转换,不要再用错了
  3. 文字和图片放一起, 文字下沉的处理方法
  4. 大数据决策支持的优势
  5. 一键恢复CGI v3.2.1.0 增强版
  6. jquery form表单提交
  7. 使用 Infiniband 实现 RDMA !IB卡介绍!下载IB 驱动 !lspci | grep Mell 查看 IB卡!
  8. 基于JSP+Servlet+Tomcat8.5+WebSocket实现的网页聊天室
  9. Unity-人物移动
  10. y-在C语言while语句中的意义,c语言while用法(C语言while用法)
  11. 有关XLS文件的读取
  12. java8 日期 时间 时区
  13. 论文阅读 点云动态图卷积(DGCNN)
  14. 华盛证券软件测试工程师工资,【恒生电子工资】软件测试工程师待遇-看准网...
  15. 最近邻插值(nearest neighbor)-----python
  16. 用Java抓取RSS生成Mobi文件发送到Kindle
  17. java 文件解压缩zip_java解压缩zip文件
  18. 什么是.vue文件,它的作用是什么
  19. 一些纳税常识[公司]
  20. 七麦数据:2018年App Store大数据半年盘点(附下载)

热门文章

  1. Leetcode 930. 和相同的二元子数组 题解
  2. 谷歌浏览器怎么同步收藏夹,书签云帮助你
  3. 一筐鸡蛋一个一个拿正好拿完java_求解:一筐鸡蛋:9个9个拿正好拿完8个8个拿还剩1个...
  4. 深度学习之YOLOv5实践应用(1)系统安装配置
  5. Java中String,StringBuffer,StringBuilder基础知识
  6. 计算商场折扣 (分支)
  7. 六轴机械臂控制原理图_机械臂——六轴机械臂操作空间运动分析
  8. MacBook随笔之eclipse常用快捷键速学
  9. WiBS区块链女性领导力系列研讨会分论坛圆满成功,打破性别偏见,重塑女性价值观
  10. iis 自定义字体 woff