linux基础复习(6)文件I/O操作
诉内核:
(1) 我们所关心的描述符。
(2) 对于每个描述符我们所关心的条件(是否读一个给定的描述符?是否想写一个给定的描述符?是否关心一个描述符的异常条件?)。
(3) 希望等待多长时间(可以永远等待,等待一个固定量时间,或完全不等待)。
从s e l e c t返回时,内核告诉我们:
(1) 已准备好的描述符的数量。
(2) 哪一个描述符已准备好读、写或异常条件。
#i nclude /* fd_set data type */
#i nclude /* struct timeval */
#i nclude /* function prototype might be here */
int select (int numfds, fd_set *readfds,
fd_set *writefds, fd_set *exceptfds, struct timeval * timeout) ;
返回:准备就绪的描述符数,若超时则为0,若出错则为- 1。
timeout值:
n NULL:永远等待,直到捕捉到信号或文件描述符已准备好为止;
n 具体值: struct timeval 类型的指针,若等待为timeout时间还没有文件描述符准备好,就立即返回;
n 0:从不等待,测试所有指定 的描述符并立即返回;
先说明最后一个参数,它指定愿意等待的时间。
struct timeval
{
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
select函数根据希望进行的文件操作对文件描述符进行分类处理,这里,对文件描述符的处理主要设计4个宏函数:
FD_ZERO(fd_set *set) 清除一个文件描述符集;
FD_SET(int fd, fd_set *set) 将一个文件描述符加入文件描述符集中;
FD_CLR(int fd, fd_set *set) 将一个文件描述符从文件描述符集中清除;
FD_ISSET(int fd, fd_set *set) 测试该集中的一个给定位是否有变化;
在使用select函数之前,首先使用FD_ZERO和FD_SET来初始化文件描述符集,并使用select函数时,可循环使用FD_ISSET测试描述符集, 在执行完成对相关的文件描述符后, 使用FD_CLR来清除描述符集。
实例
/*select.c*/
#i nclude fcntl.h>
#i nclude stdio.h>
#i nclude unistd.h>
#i nclude stdlib.h>
#i nclude sys/time.h>
int main(void)
{
int fds[2];
char buf[7];
int i,rc,maxfd;
fd_set inset1,inset2;
struct timeval tv;
if((fds[0] = open (hello1, O_RDWR|O_CREAT,0666))0)
perror(open hello1);
if((fds[1] = open (hello2, O_RDWR|O_CREAT,0666))0)
perror(open hello2);
if((rc = write(fds[0],Hello!\n,7)))
printf(rc=%d\n,rc);
lseek(fds[0],0,SEEK_SET);
maxfd = fds[0]>fds[1] ? fds[0] : fds[1];
//初始化读集合 inset1,并在读集合中加入相应的描述集
FD_ZERO(inset1);
FD_SET(fds[0],inset1);
//初始化写集合 inset2,并在写集合中加入相应的描述集
FD_ZERO(inset2);
FD_SET(fds[1],inset2);
tv.tv_sec=2;
tv.tv_usec=0;
// 循环测试该文件描述符是否准备就绪,并调用 select 函数对相关文件描述符做相应操作
while(FD_ISSET(fds[0],inset1)||FD_ISSET(fds[1],inset2))
{
if(select(maxfd+1,inset1,inset2,NULL,tv)0)
perror(select);
else{
if(FD_ISSET(fds[0],inset1))
{
rc = read(fds[0],buf,7);
if(rc>0)
{
buf[rc]='\0';
printf(read: %s\n,buf);
}else
perror(read);
}
if(FD_ISSET(fds[1],inset2))
{
rc = write(fds[1],buf,7);
if(rc>0)
{
buf[rc]='\0';
printf(rc=%d,write: %s\n,rc,buf);
}else
perror(write);
sleep(10);
}
}
}
exit(0);
}
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)