一、文件控制函数
         fcntl -- file control

LIBRARY
         Standard C Library (libc, -lc)

SYNOPSIS
         #include ;

int fcntl(int fd, int cmd, ...);

【描述】:

fcntl()针对文件描述符提供控制,参数fd 是被参数cmd操作的描述符.

针对cmd的值,fcntl能够接受第三个参数int arg

二、fcntl函数有5种功能:

1.复制一个现有的描述符(cmd=F_DUPFD).

2.获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).

3.获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).

4.获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).

5.获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW).

【cmd值】 :

F_DUPFD          返回一个如下描述的(文件)描述符:

o            最小的大于或等于arg的一个可用的描述符

o            与原始操作符一样的某对象的引用

o            如果对象是文件(file)的话,返回一个新的描述符,这个描述符与arg 共享相同的偏移量(offset)

o            相同的访问模式(读,写或读/写)

o            相同的文件状态标志(如:两个文件描述符共享相同的状态标志)

o            与新的文件描述符结合在一起的close-on-exec 标志被设置成交叉式访问execve(2)的系统调用

F_GETFD          取得与文件描述符fd联合close-on-exec标志,类似FD_CLOEXEC.如果返回值和FD_CLOEXEC进行与运算结果是0的话,文件保持交叉式访问exec(),否则如果通过exec运行的话,文件将被关闭(arg 被忽略)

F_SETFD           设置close-on-exec 旗标。该旗标以参数arg 的FD_CLOEXEC位决定。

F_GETFL           取得fd的文件状态标志,如同下面的描述一样(arg被忽略)

F_SETFL            设置给arg描述符状态标志,可以更改的几个标志是: O_APPEND, O_NONBLOCK,O_SYNC和O_ASYNC。

F_GETOWN       取得当前正在接收SIGIO或者SIGURG信号的进程id或进程组id,进程组id返回成负值(arg被忽略)

F_SETOWN        设置将接收SIGIO和SIGURG信号的进程id或进程组id,进程组id通过提供负值的arg来说明,否则,arg将被认为是进程id

命令字(cmd)F_GETFL和F_SETFL的标志如下面的描述:

O_NONBLOCK      非阻塞I/O;如果read(2)调用没有可读取的数据,或者如果write(2)操作将阻塞,read或write调用返回-1和EAGAIN错误

O_APPEND             强制每次写(write)操作都添加在文件大的末尾,相当于open(2)的O_APPEND标志

O_DIRECT                最小化或去掉reading和writing的缓存影响.系统将企图避免缓存你的读或写的数据.如果不能够避免缓存,那么它将最小化已经被缓存了的数据造成的影响.如果这个标志用的不够好,将大大的降低性能

O_ASYNC                  当I/O可用的时候,允许SIGIO信号发送到进程组,例如:当有数据可以读的时候

在修改文件描述符标志或文件状态标志时必须谨慎,先要取得现在的标志值,然后按照希望修改它,最后设置新标志值。不能只是执行F_SETFD或F_SETFL命令,这样会关闭以前设置的标志位。

fcntl的返回值与命令有关:如果出错,所有命令都返回-1,如果成功则返回某个其他值。下列三个命令有特定返回值:

F_DUPFD返回新的文件描述符

F_GETFD,F_GETFL返回相应标志

F_GETOWN返回一个正的进程ID或负的进程组ID

三、控制fd的例程如下:

#include

#include

#include

#include

using namespace std;

int main(int argc,char* argv[])

{

int fd,var;

// fd=open("new",O_RDWR);

if (argc!=2)

{

perror("--");

cout<<"请输入参数,即文件名!"<

}

if((var=fcntl(atoi(argv[1]), F_GETFL, 0))<0)

{

strerror(errno);

cout<<"fcntl file error."<

}

/**三个存取方式标志(O_RDONLY,  O_WRONLY,以及  O_RDWR)并不各占1位。(这三种标志的值各是0、1和2,由于历史原因。这三种值互斥—一个文件只能有这三种值之一。)因此首先必须用屏蔽字O_ACCMODE取得存取方式位,然后将结果与这三种值相比较。**/

switch(var & O_ACCMODE)

{

case O_RDONLY : cout<<"Read only.."<

break;

case O_WRONLY : cout<<"Write only.."<

break;

case O_RDWR : cout<<"Read wirte.."<

break;

default : break;

}

if (val & O_APPEND)

cout<<",append"<

if (val & O_NONBLOCK)

cout<<",noblocking"<

cout<<"exit 0"<

exit(0);

}

四、使用第三个参数arg参数文件的close_on_exec标志

1>阻塞IO 与 非阻塞IO
1.阻塞IO 
a.编程简单
b.如果数据不来,什么都干不了
2.非阻塞IO(轮询)
a.以轮询的方式判断是否有数据需要处理,如果没有,可以做一些其他事情
b.如果有,就处理数据

int flags = fcntl(STDIN_FILENO,F_GETFL);
flags |= O_NONBLOCK;
fcntl(STDIN_FILENO,F_SETFL,flags);

五、 获得/设置记录锁的功能:(cmd=F_GETLK,F_SETLK或F_SETLKW).

F_GETLK  通过第三个参数arg(一个指向flock的结构体)取得第一个阻塞lock description指向的的锁.取得的信息将覆盖传到fcntl()的flock结构的信息.如果没有发现能够阻止本次锁(flock)生成的锁,这个结构将不被改变,除非锁的类型被设置成F_UNLCK.

F_SETLK       按照指向结构体flock的指针的第三个参数arg所描述的锁的信息设置或者清除一个文件segment锁.F_SETLK被用来实现共享(或读)锁 (F_RDLCK)或独占(写)锁(F_WRLCK),同样可以去掉这两种锁(F_UNLCK).如果共享锁或独占锁不能被设置,fcntl()将立即返回EAGAIN.

F_SETLKW    除了共享锁或独占锁被其他的锁阻塞这种情况外,这个命令和F_SETLK是一样的.如果共享锁或独占锁被其他的锁阻塞,进程将等待直到这个请求能够完成. 当fcntl()正在等待文件的某个区域的时候捕捉到一个信号,如果这个信号没有被指定SA_RESTART,fcntl将被中断.

当一个共享锁被set到一个文件的某段的时候,其他的进程可以set 共享锁到这个段或这个段的一部分.共享所阻止任何其他进程set独占锁到这段保护区域的任何部分.如果文件描述符没有以读的访问方式打开的话,共享锁的设置请求会失败

独占锁阻止任何其他的进程在这段保护区域任何位置设置共享锁或独占锁.如果文件描述符不是以写的访问方式打开的话,独占锁的请求会失败

结构体flock的指针:

struct flcok

{

short int l_type; /* 锁定的状态*/

//这三个参数用于分段对文件加锁,若对整个文件加锁,则:l_whence=SEEK_SET,l_start=0,l_len=0;

short int l_whence;/*决定l_start位置*/

off_t l_start; /*锁定区域的开头位置*/

off_t l_len; /*锁定区域的大小*/

pid_t l_pid; /*锁定动作的进程*/

};

l_type 有三种状态:

F_RDLCK  建立一个供读取用的锁定

F_WRLCK建立一个供写入用的锁定

F_UNLCK删除之前建立的锁定

l_whence 也有三种方式:

SEEK_SET以文件开头为锁定的起始位置。

SEEK_CUR以目前文件读写位置为锁定的起始位置

SEEK_END以文件结尾为锁定的起始位置。

返回值成功则返回0,若有错误则返回-1,错误原因存于errno。

函数fcntl的用法相关推荐

  1. MSSQL Sql加密函数 hashbytes 用法简介

    原文:MSSQL Sql加密函数 hashbytes 用法简介 转自:http://www.maomao365.com/?p=4732 一.mssql sql hashbytes 函数简介 hashb ...

  2. 字符串函数用法 php,PHP字符串函数print()的用法

    print (PHP 4, PHP 5) print - 输出字符串 说明 int print ( string $arg ) 输出 arg. print 实际上不是一个函数(它是一个语言结构),因此 ...

  3. ROW_NUMBER() OVER函数的基本用法用法

    ROW_NUMBER() OVER函数的基本用法用法 转自:http://www.cnblogs.com/icebutterfly/archive/2009/08/05/1539657.html 语法 ...

  4. python用psf函数_Python 嵌套函数(高级用法)

    Python 嵌套函数(高级用法) 一.嵌套函数(高级用法) 1.嵌套函数 函数的嵌套调用是在"函数调用中再调用其他函数".也就是说:函数嵌套允许在一个函数中调用另外一个函数.如下 ...

  5. php数组函数及用法,php数组函数 in_array 的用法及注意事项

    php中操作数组的函数很多,in_array就是其中一个. in_array函数 用于检查是否存在一个值的数组,即它可以判断当前数组中是否存在一个指定的值. in_array (PHP 4, PHP ...

  6. python中tile的用法_python3中numpy函数tile的用法详解

    tile函数位于python模块 numpy.lib.shape_base中,他的功能是重复某个数组.比如tile(A,n),功能是将数组A重复n次,构成一个新的数组,我们还是使用具体的例子来说明问题 ...

  7. 【转】typedef函数指针的用法(C++)

    原文: typedef函数指针的用法(C++) 代码简化, 促进跨平台开发的目的. typedef 行为有点像 #define 宏,用其实际类型替代同义字. 不同点:typedef 在编译时被解释,因 ...

  8. typedef 函数指针的用法

    进入正文: 代码简化, 促进跨平台开发的目的. typedef 行为有点像 #define 宏,用其实际类型替代同义字. 不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文 ...

  9. PHP错误处理函数set_error_handler()的用法

    定义和用法 set_error_handler() 函数设置用户自定义的错误处理函数. 该函数用于创建运行时期间的用户自己的错误处理方法. 该函数会返回旧的错误处理程序,若失败,则返回 null. 语 ...

最新文章

  1. oracle 时间减去一个月_一文看懂教孩子时间问题的进阶过程
  2. c++ 三次多项式拟合_非线性回归模型(一)--多项式回归
  3. 汽车销售系统javaweb代码_有什么代驾系统能远离销售套路_搜狐汽车
  4. PWN-PRACTICE-BUUCTF-14
  5. Django环境配置
  6. 手写分页 个人感觉还能优化,甚至抽象出来,需要高手讲解
  7. 【转】vb获得网络时间的函数
  8. 电商刮刮卡开发基础准备
  9. koa2从搭建项目到实现API
  10. mBlock机器人组装教程_mbot机器人如何搭建?mBot机器人套件快速搭建指南
  11. 2019数据安装勾选_怎么安装勾选平台控件,如何网上勾选认证发票?
  12. Linux开启root用户
  13. DenseBox Unifying Landmark Localization with End to End Object Detection
  14. C# 简单判断枚举值是否被定义
  15. 五个最适合做博客的开源系统 开源免费大量精美模板使用!
  16. 使用UVCCamera拍照后zbar与zxing识别图片中的二维码
  17. 服务器显示资源不够用,Docker服务器存储资源池不足的问题解决
  18. bios怎么设置USB启动
  19. kali-linux u盘便携性系统,暗组u盘怎么进入kali linux系统
  20. 双目立体视觉几何框架详解

热门文章

  1. 火山安卓-车票查询软件
  2. 仿最新BiliBili客户端开源带后台弹幕库版
  3. 教育知识与能力简答题汇总
  4. 笑话大全查询易语言代码
  5. 【KEIL MDK使用AStyle程序格式化操作】
  6. linux下Hadoop安装与环境配置
  7. 火车票抢票程序【selenium】【python】
  8. 对绝缘子污闪以及绝缘子干冰清洗方法的探讨研究
  9. tiledmap 图块属性_tiledmap 可以在图块层的指定格子上添加Sprite吗
  10. 遗传算法的运用(Python版)