(转)关于unix/linux体系中的文件描述符fdITeye - 威尼斯人

(转)关于unix/linux体系中的文件描述符fdITeye

2019年02月25日11时37分41秒 | 作者: 访烟 | 标签: 文件,体系,设置 | 浏览: 2552

一、文件描绘符和途径指定文件的差异
在unix/linux体系中,文件描绘符的效果就是标识现已翻开的文件(留意Linux中一切的I/O设备都是以文件的方法拜访!),留意,是现已翻开的文件,并不包括没有翻开的文件。所以,用文件描绘符fd来指定一个文件,就意味着该文件现已被翻开。而用途径名来指定一个文件,该文件既可所以翻开的,也可所以未翻开的。
按照上名的解说,你就能很简单的理解以下几个函数之间的差异了
在unix/linux体系中,stat()和 fstat()函数的原型如下:
int stat(const char *pathname,struct stat *buf);
int fstat(int filedes,struct stat *buf);
这两个函数的共同点是用来取得文件的struct stat信息结构
不同点是stat函数取得途径名pathname指定的文件的信息结构,该文件既可所以现已被翻开的,也可所以未被翻开的;而 fstat函数是取得在文件描绘符filedes上翻开的文件的信息结构
同样地,下面两个函数的差异也是相同的
int chmod(const char *pathname,mode_t mode);
int fchmod(int filedes,mode_t mode);

二、Select()体系调用及文件描绘符集fd_set的运用
在网络程序中,一个进程一起处理多个文件描绘符是很常见的状况。select()体系调用能够使进程检测一起等候的多个I/O设备,当没有设备准备好时,select()堵塞,其间任一设备准备好时,select()就回来。
select()的调用方式为:
#include sys/select.h
#include sys/time.h
int select(int maxfd, fd_set *readfds, fd_set *writefds, fe_set *exceptfds, const struct timeval *timeout);
select的第一个参数是文件描绘符会集要被检测的比特数,这个值有必要至少比待检测的最大文件描绘符大 1;参数readfds指定了被读监控的文件描绘 符集;参数writefds指定了被写监控的文件描绘符集;而参数exceptfds指定了被破例条件监控的文件描绘符集。
参数timeout起了定时器的效果:到了指定的时刻,不管是否有设备准备好,都回来调用。timeval的结构界说如下:
struct timeval{
long tv_sec; //表明几秒
long tv_usec; //表明几奇妙
}
timeout取不同的值,该调用就体现不同的性质:
1.timeout为0,调用当即回来;
2.timeout为NULL,select()调用就堵塞,直到知道有文件描绘符安排妥当;
3.timeout为正整数,就是一般的定时器。
select调用回来时,除了那些现已安排妥当的描绘符外,select将铲除readfds、writefds和exceptfds中的一切没有安排妥当的描绘符。select的回来值有如下状况:
1.正常状况下回来安排妥当的文件描绘符个数;
2.经过了timeout时长后仍无设备准备好,回来值为0;
3.假如select被某个信号中止,它将回来-1并设置errno为EINTR。
4.假如犯错,回来-1并设置相应的errno。
体系供给了4个宏对描绘符集进行操作:
#include sys/select.h
#include sys/time.h
void FD_SET(int fd, fd_set *fdset);
void FD_CLR(int fd, fd_set *fdset);
void FD_ISSET(int fd, fd_set *fdset);
void FD_ZERO(fd_set *fdset);
宏FD_SET设置文件描绘符集fdset中对应于文件描绘符fd的位(设置为 1),宏FD_CLR 铲除文件描绘符集 fdset中对应于文件描绘符fd的 位(设置为0),宏FD_ZERO 铲除文件描绘符集 fdset中的一切位(既把一切位都设置为0)。运用这3个宏在调用select前设置描绘符屏蔽位, 在调用select后运用FD_ISSET 来检测文件描绘符集 fdset中对应于文件描绘符fd的位是否被设置。
曩昔,描绘符集被作为一个整数位屏蔽码得到完成,可是这种完成关于多于32个的文件描绘符将无法作业。描绘符集现在一般用整数数组中的位域表明,数组元素 的每一位对应一个文件描绘符。例如,一个整数占32位,那么整数数组的第一个元素代表文件描绘符0 到31,数组的第二个元素代表文件描绘符32到63,以 此类推。宏FD_SET设置整数数组中对应于fd文件描绘符的位为1,宏FD_CLR设置整数数组中对应于fd文件描绘符的位为 0,宏FD_ZERO 设置 整数数组中的一切位都为0。假定履行如下程序后:
#include sys/select.h
#include sys/time.h
fd_set readset;
FD_ZERO( readset);
FD_SET(5, readset);
FD_SET(33, readset);
则文件描绘符集readset中对应于文件描绘符6和33的相应位被置为1,如图1所示:

再履行如下程序后:
FD_CLR(5, readset);
则文件描绘符集readset对应于文件描绘符6的相应位被置为0,如图2所示:


一般,操作体系经过宏FD_SETSIZE来声明在一个进程中select所能操作的文件描绘符的最大数目。例如:
在4.4BSD的头文件中咱们能够看到:
#ifndef FD_SETSIZE
#define FD_SETSIZE 1024
#endif
在红帽Linux的头文件 bits/types.h 中咱们能够看到:
#define __FD_SETSIZE 1024
以及在头文件 sys/select.h 中咱们能够看到:
#include bits/types.h
#define FD_SETSIZE __FD_SETSIZE
既界说FD_SETSIZE为1024,一个整数占4个字节,既32 位,那么就是用包括32个元素的整数数组来表明文件描绘符集。咱们能够在头文件中修正 这个值来改动select运用的文件描绘符集的巨细,可是有必要从头编译内核才能使修正后的值有用。当时版别的unix操作体系没有约束 FD_SETSIZE的最大值,一般只受内存以及体系管理上的约束。

转自:

http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表威尼斯人立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章