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

函数原型:

  1. #include<unistd.h>
  2. #include<fcntl.h>
  3. int fcntl(int fd, int cmd);
  4. int fcntl(int fd, int cmd, long arg);
  5. 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指定方式

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

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

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

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

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结构。

非阻塞I/O使我们的操作要么成功,要么立即返回错误,不被阻塞

实例

if ((rsck = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
{
#ifdef DEBUGprintf("Failed to initialize raw socket\n");
#endifexit(0);
}// 设置非堵塞,作要么成功,要么立即返回错误,不被阻塞
fcntl(rsck, F_SETFL, O_NONBLOCK | fcntl(rsck, F_GETFL, 0));

C/C++进程文件锁 之 fcntl函数的用法总结(非阻塞O_NONBLOCK)相关推荐

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

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

  2. linux fcntl 函数 文件描述符选项控制

    功能描述:根据文件描述词来操作文件的特性. #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); ...

  3. fcntl函数详解【转】

    (转自:https://blog.csdn.net/pbymw8iwm/article/details/7974789) 功能描述:根据文件描述词来操作文件的特性. #include <unis ...

  4. linux / fcntl 函数详解

    零.作用 fcntl() 针对(文件)描述符提供控制. 复制一个现有的描述符(cmd = F_DUPFD). 获得/设置文件描述符标记(cmd = F_GETFD 或 F_SETFD). 获得/设置文 ...

  5. Linux文件锁和fcntl系统调用

    1.Linux 中的文件锁 Linux 支持的文件锁技术主要包括劝告锁(advisory lock)和强制锁(mandatory lock)这两种.此外,Linux 中还引入了两种强制锁的变种形式:共 ...

  6. 在Python中对子进程进行非阻塞读取

    我正在使用子流程模块来启动子流程并连接到其输出流(stdout). 我希望能够在其stdout上执行非阻塞读取. 有没有一种方法可以使.readline成为非阻塞状态,或者在调用.readline之前 ...

  7. 文件描述符和fcntl及阻塞非阻塞

    Linux 文件描述符和重定向 https://www.cnblogs.com/chenmh/p/5382044.html fcntl函数的用法总结 https://www.cnblogs.com/z ...

  8. 【Linux】进程等待wait/waitpid status详解 (非)阻塞等待(代码)

    文章目录 进程等待原因 进程等待方法 wait waitpid 获取子进程status (非)阻塞等待 进程的非阻塞等待方式代码 进程的阻塞等待方式代码 进程等待原因 fork创建了子进程,子进程帮父 ...

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

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

最新文章

  1. RTX组织架构刷新出现了问题
  2. [原创]Javascript类成员的作用域
  3. Let Me Count The Ways(Kickstart Round H 2018)
  4. 对学校的希望和寄语_家长对孩子的期望寄语精选
  5. php源代码压缩,PHP_PHP 源代码压缩小工具,使用方法:(在命令行运行) 复 - phpStudy...
  6. Java并发编程--CountDownLatch
  7. Python爬虫实现:三连文章参与抽奖
  8. 1.5 编程基础之循环控制 44 第n小的质数
  9. sql cast()函数
  10. Java使用循环创建多个线程
  11. JAVA基础之列表(list)和字典(dict)
  12. 《算法导论》第三版第6章 堆排序 练习思考题 个人答案
  13. matlab求统计量:均值/中位数/极值/方差和标准差
  14. python语句只能以程序方式打开_python如何处理程序无法打开
  15. 学会Apache网页与安全的优化,让你的技术更加胜人一筹!(网页压缩与缓存、隐藏版本信息与配置防盗链)
  16. 苹果尝试支持AdobeFlash,结果尴尬了
  17. 如何将硬盘分区合并不丢失数据,合并两个硬盘分区不删除数据
  18. Linux操作系统基础之用户管理
  19. 口令登陆创新的一些想法
  20. 基于微信小程序电商平台

热门文章

  1. Mac免费软件推荐:Wireshark for Mac(网络分析器)
  2. 可持久化数据结构、可并堆
  3. 1.3编程基础之算术表达式与顺序执行 02 计算(a+b)*c的值
  4. php5.4.45的php.ini文件
  5. python读取txt文件每一行存为列表,从txt文件中读取一定数量的行,并以python方式转换为list...
  6. 活跃用户数怎么计算_【数据运营】|如何做好活跃用户的运营?
  7. linux 程序收到sigsegv信号_linux下定位多线程内存越界问题实践总结
  8. Qt工作笔记-对QImage的进一步认识(关于α通道)
  9. linux apache目录权限配置,Linux下Apache网站目录读写权限的设置
  10. baseapp01: [S_ERROR]: [Account 40 => dbid 196]---------->call server client2base_xz Generate an err