一、文件描述符和路径指定文件的区别
在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://hi.baidu.com/joec3/blog/item/2a73ff1ef2d3a3f81ad576e2.html
http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html
分享到:
相关推荐
在Linux操作系统中,文件描述符(File Descriptor, fd)和文件指针(FILE *)是两种不同的方式,用于访问和操作文件。它们各自有其特点和应用场景,有时需要在两者之间进行转换。以下是对这两个概念的详细解释以及...
在Unix和类Unix系统中,文件描述符通常是一个非负整数,其中0、1、2分别默认指向标准输入、标准输出和标准错误输出。本文将深入探讨与文件描述符操作相关的几个关键概念和特性,特别关注于参数`fd`和`cmd`的使用。 ...
总的来说,Unix域套接字传递描述符是Unix/Linux系统中进程间通信的一个强大特性,它使得资源管理更加灵活,提高了系统的可扩展性和效率。理解并熟练运用这一特性对于开发高效、低延迟的系统级软件至关重要。
- **地址表示**:UNIX域套接字的地址通常由文件系统的路径名表示。一旦创建,该套接字就会绑定到这个路径名。尽管这些文件看起来像是普通的文件,但不能通过`open()`函数打开,而是需要通过套接字API进行操作。 ###...
文件描述符是Linux系统中对打开文件的一种抽象表示,每个进程都有一个文件描述符表,用于管理其打开的文件或套接字等资源。本示例代码将探讨如何在两个进程之间传递文件描述符,以实现数据共享。 首先,我们来看`...
Ashmem是Android系统特有的内存管理机制,它创建的内存区域是匿名的,即不在文件系统中有对应的文件。但是,Ashmem分配的内存可以像文件一样通过文件描述符(File Descriptor)进行操作。这样,一个进程创建的Ashmem...
- **系统调用处理**:当用户空间程序发起系统调用时,VFS会根据文件描述符定位到对应的文件系统,并调用相应的操作函数来完成请求。 通过以上介绍可以看出,Linux文件系统不仅在技术层面具有高度的灵活性和扩展性,...
在Linux操作系统中,文件描述符是系统内核用于标识打开文件的一种抽象标识。每个进程都有一个文件描述符表,其中包含了进程打开的所有文件的描述符。文件描述符从0开始,通常0、1、2分别对应标准输入、标准输出和...
在UNIX/Linux系统中,文件描述符是一个用于表征打开文件的整数。每个进程都拥有一个文件描述符表,用于管理文件和其他I/O资源。 **虚拟文件系统(VFS):** 虚拟文件系统是一个抽象层,它为不同的文件系统提供了一...
操作系统实验八专注于文件系统调用,旨在让学生熟悉和掌握在Unix/Linux环境下操作文件和目录的基本System Call,同时深入了解Unix/Linux文件系统的结构、特殊文件的作用以及如何进行操作。实验要求独立完成,包括...
`dup2(fd, STDOUT_FILENO)`使得标准输出(文件描述符1)指向`myout`文件。因此,`printf`的内容会被写入`myout`文件。 2.6 文件复制: 这部分要求编写一个程序,使用`read`和`write`函数从源文件读取数据并写入目标...
文件描述符是Unix/Linux中每个打开文件的唯一标识。0通常代表标准输入,1代表标准输出,2代表标准错误。其他的文件描述符是通过`open`函数分配的。 7. **C语言编程**: `first_unix.c`是一个C语言源代码文件,...
在UNIX操作系统中,文件系统的管理是其核心部分,而UNIX V6++作为早期的UNIX版本,其设计思想和实现机制对于理解现代UNIX/Linux文件系统有着重要的作用。以下是关于UNIX V6++文件系统的一些关键知识点: 1. **文件...
文件描述符的范围是 0 ~ OPEN_MAX,早期的 Unix 版本采用的上限值是 19,现在很多系统则将其增加至 63。 三、open 函数 open 函数可以打开或创建一个文件。该函数的原型是: `int open(const char *path, int ...
在Linux或类Unix操作系统中,每个打开的文件都关联一个整型值,称为文件描述符(File Descriptor, fd)。文件描述符是非负整数,其中标准输入、标准输出和标准错误输出分别对应的文件描述符为0、1和2。 - **fd_set*...
11. `write(fd, buf, n)`: 将buf中的n个字节写入文件描述符fd所指向的文件。 12. `close(fd)`: 关闭已打开的文件描述符fd。 13. `dup(fd)`: 复制文件描述符fd。 14. `pipe(p)`: 创建一个管道,返回一对文件描述符,...
对于文件系统的理解和操作,如软硬链接、文件时间戳、目录的读取等,也是UNIX系统编程的关键技能之一。 书中还包括了对一些UNIX系统特有功能的解释,例如/dev/fd、设备特殊文件、文件大小的获取和修改等。 此外,...
IO多路复用是一种高效的系统调用机制,它允许单个进程同时监控多个文件描述符(file descriptor),等待它们中的任意一个或多个准备就绪,以便进行读写操作。在Unix/Linux系统中,最常用的IO多路复用方法包括select...
在Linux中,每个打开的文件都会有一个唯一的文件描述符(File Descriptor, FD),通常从0开始,0通常是标准输入,1是标准输出,2是标准错误。程序可以通过文件描述符来访问和操作文件。 2. **打开与关闭文件**: ...
- 创建:使用`pipe()`系统调用创建一对文件描述符,一个用于读取(`read`),另一个用于写入(`write`)。 - 使用:通常在父进程中创建管道,然后通过`fork()`创建子进程。父进程通过管道写端向管道发送数据,子进程...