函数fcntl的用法
一、文件控制函数
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的用法相关推荐
- MSSQL Sql加密函数 hashbytes 用法简介
原文:MSSQL Sql加密函数 hashbytes 用法简介 转自:http://www.maomao365.com/?p=4732 一.mssql sql hashbytes 函数简介 hashb ...
- 字符串函数用法 php,PHP字符串函数print()的用法
print (PHP 4, PHP 5) print - 输出字符串 说明 int print ( string $arg ) 输出 arg. print 实际上不是一个函数(它是一个语言结构),因此 ...
- ROW_NUMBER() OVER函数的基本用法用法
ROW_NUMBER() OVER函数的基本用法用法 转自:http://www.cnblogs.com/icebutterfly/archive/2009/08/05/1539657.html 语法 ...
- python用psf函数_Python 嵌套函数(高级用法)
Python 嵌套函数(高级用法) 一.嵌套函数(高级用法) 1.嵌套函数 函数的嵌套调用是在"函数调用中再调用其他函数".也就是说:函数嵌套允许在一个函数中调用另外一个函数.如下 ...
- php数组函数及用法,php数组函数 in_array 的用法及注意事项
php中操作数组的函数很多,in_array就是其中一个. in_array函数 用于检查是否存在一个值的数组,即它可以判断当前数组中是否存在一个指定的值. in_array (PHP 4, PHP ...
- python中tile的用法_python3中numpy函数tile的用法详解
tile函数位于python模块 numpy.lib.shape_base中,他的功能是重复某个数组.比如tile(A,n),功能是将数组A重复n次,构成一个新的数组,我们还是使用具体的例子来说明问题 ...
- 【转】typedef函数指针的用法(C++)
原文: typedef函数指针的用法(C++) 代码简化, 促进跨平台开发的目的. typedef 行为有点像 #define 宏,用其实际类型替代同义字. 不同点:typedef 在编译时被解释,因 ...
- typedef 函数指针的用法
进入正文: 代码简化, 促进跨平台开发的目的. typedef 行为有点像 #define 宏,用其实际类型替代同义字. 不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文 ...
- PHP错误处理函数set_error_handler()的用法
定义和用法 set_error_handler() 函数设置用户自定义的错误处理函数. 该函数用于创建运行时期间的用户自己的错误处理方法. 该函数会返回旧的错误处理程序,若失败,则返回 null. 语 ...
最新文章
- CCNP-22 路由重发布2(BSCI)
- WPF 加载等待动画
- linux 操作mysql 数据库命令_在Linux上用命令怎么连接数据库
- 线程池的种类,区别和使用场景
- @RequestMapping 和 @GetMapping @PostMapping 区别
- union共用体(联合体)、宏定义、枚举
- Ubuntu 16.04-17.04开机自动root用户登录(测试可用)
- 摄影基础知识:等效焦距是什么?
- Mysql报错Fatal error occurred in the transaction branch - check your data for consistency
- 《南溪的目标检测学习笔记》——主干网络backbone设计的学习笔记
- [POJ2195]Going Home(带权最大匹配,KM,最小费用流)
- 解决同一条sql在pl/sql工具中执行很快,在程序中却很慢
- 专网解决方案:中兴以全光园区解决方案打造智慧园区
- (二十三)Java工具类ToStringBuilder方法详解
- Axure RP 8 Pro 破解版软件安装包
- 百度api实现实时摄像头人脸识别
- 怎样在网站中添加google统计代码
- jquery 实现的省市区级联,无ajax
- C:\Users\用户名\Documents不可用
- vue,的M、V、VM分别代表什么