fd_set解析
来源:互联网 发布:手机微信刷屏软件 编辑:程序博客网 时间:2024/05/14 18:32
用到select,就难免不了要接触一下几个宏
fd_set set;
FD_ZERO(&set);
FD_SET(read_fd,&set);
select(MAX_NUM+1,&set,NULL,NULL,NULL);
if(FD_ISSET(read_fd,set){……}
这几个经常是按这种次序组合出现的,之前虽然也用过,但说实话,也就是用,根本不知道怎么回事,现在有了初步的了解。
首先是 fd_set,这是什么?其实这是一个数组的宏定义,数组的类型是(unsigned) long型的(个人推测无符号),占有128位,无论是32位的linux下,还是64位下,他都是128个字节(128*8位=1024位,也就是可以检测1024个任务,这也是select默认的个数,可以通过编译内核修改),但是由于不同位数的系统下long型的长度不同,所以导致数组的元素个数也是不同的。理解fd_set可以根据位图的方式来理解。
代码:
#include <stdio.h>#include <sys/select.h>#include <unistd.h>int main(void){ fd_set fdset; FD_ZERO (&fdset); FD_SET(STDIN_FILENO,&fdset); FD_SET(STDOUT_FILENO,&fdset); FD_SET(STDERR_FILENO,&fdset); FD_SET(7,&fdset); if(FD_ISSET(STDOUT_FILENO,&fdset)!=0) printf("stdout has been set\n"); else printf("stdout has not been set\n"); FD_CLR(STDOUT_FILENO,&fdset); if(FD_ISSET(STDOUT_FILENO,&fdset)!=0) printf("stdout has been set\n"); else printf("stdout has not been set\n"); return 0;}
下面是我的简单调试
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-42.el5)Copyright (C) 2009 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "x86_64-redhat-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /home/fy/SystemV_ipc/select/run...done.(gdb) l1 #include <stdio.h>2 #include <sys/select.h>3 #include <unistd.h>4 int main(void)5 {6 fd_set fdset;7 FD_ZERO (&fdset);8 FD_SET(STDIN_FILENO,&fdset);9 FD_SET(STDOUT_FILENO,&fdset);10 FD_SET(STDERR_FILENO,&fdset);(gdb) b 7 Breakpoint 1 at 0x4004a3: file select.c, line 7.(gdb) b 8Breakpoint 2 at 0x4004d2: file select.c, line 8.(gdb) b 9Breakpoint 3 at 0x4004e4: file select.c, line 9.(gdb) b 10Breakpoint 4 at 0x4004f6: file select.c, line 10.(gdb) l11 FD_SET(7,&fdset);12 if(FD_ISSET(STDOUT_FILENO,&fdset)!=0)13 printf("stdout has been set\n");14 else15 printf("stdout has not been set\n");16 FD_CLR(STDOUT_FILENO,&fdset);17 if(FD_ISSET(STDOUT_FILENO,&fdset)!=0)18 printf("stdout has been set\n");19 else20 printf("stdout has not been set\n");(gdb) b 11Breakpoint 5 at 0x400508: file select.c, line 11.(gdb) b 12Breakpoint 6 at 0x400518: file select.c, line 12.(gdb) rStarting program: /home/fy/SystemV_ipc/select/run warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000Breakpoint 1, main () at select.c:77 FD_ZERO (&fdset);(gdb) p fdset 注释:在执行FD_ZERO (&fdset);可以看下fdset里面到底放着什么$1 = {__fds_bits = {0, 15774429, 194, 15774429, 140737488348710, 140737488348711, 0, 267984686016, 4195728, 4195203, 705412764499181569, 4195783, 0, 267984686016, 4195728, 0}}(gdb) p sizeof(fdset)注释:看看fdset有多少位$2 = 128(gdb) cContinuing.Breakpoint 2, main () at select.c:88 FD_SET(STDIN_FILENO,&fdset);(gdb) p fdset 注释:在执行FD_ZERO (&fdset);后可以看下fdset里面到底放着什么,这也告诉了我们FD_ZERO的作用$3 = {__fds_bits = {0 <repeats 16 times>}}注释:我的系统是64位,long占有8个字节,128个字节空间,所以是<repeats 16 times>(gdb) cContinuing.也就是一个有16个元素的数组Breakpoint 3, main () at select.c:99 FD_SET(STDOUT_FILENO,&fdset);(gdb) p fdset 注释:在执行FD_SET(STDIN_FILENO,&fdset);STDIN_FILENO为标准输入为0 最低八位00000001,0占了第0位$4 = {__fds_bits = {1, 0 <repeats 15 times>}}(gdb) cContinuing.Breakpoint 4, main () at select.c:1010 FD_SET(STDERR_FILENO,&fdset);(gdb) p fdset$5 = {__fds_bits = {3, 0 <repeats 15 times>}}注释:加入了STDOUT(1),最低八位为00000011,所以FD_SET应该是设置位的(gdb) cContinuing.Breakpoint 5, main () at select.c:1111 FD_SET(7,&fdset);(gdb) p fdset$6 = {__fds_bits = {7, 0 <repeats 15 times>}}注释:加入了标准出粗输出(2),最低八位为00000111==7(gdb) cContinuing.Breakpoint 6, main () at select.c:1212 if(FD_ISSET(STDOUT_FILENO,&fdset)!=0)注释:j加入了自定义7后,最低八位10000111==135(gdb) p fdset$7 = {__fds_bits = {135, 0 <repeats 15 times>}}(gdb) cContinuing.stdout has been setstdout has not been setProgram exited normally.(gdb)OK。这就是fd_set。
经过这个调试输出,那么对于这几个宏的作用,一定不会陌生了吧。
FD_ZERO(&set); /*将set清零使集合中不含任何fd*/
FD_SET(fd, &set); /*将fd加入set集合*/
FD_CLR(fd, &set); /*将fd从set集合中清除*/
FD_ISSET(fd, &set); /*测试fd是否在set集合中*/
对于这几个宏的实现,自然越是难事,只要你位操作熟练掌握。
PS:另外说一下,STDIN_FILENO==0,STDOUT_FILENO=1,STDERR_FILENO==2,这也说明了为什么我们建立某些文件描述符从3开始。
- fd_set解析
- fd_set解析
- fd_set
- fd_set
- fd_set
- FD_SET
- fd_set....
- fd_set
- FD_SET
- fd_set
- fd_set
- fd_set
- fd_set
- fd_set
- fd_set
- FD_SET
- fd_set
- fd_set 用法
- 草根IT男试用期工作总结
- 趣味:女人与编程语言
- coach high level member
- error和exception
- 异地恋,你怎么看?
- fd_set解析
- 相亲其实没有那么难!
- 二元查找树的后序遍历结果[数据结构]
- ArrayList 和Vector
- java程序中,数据验证,如何判断输入的文本框中的值是不是int型?
- 数据库脏读、不可重复读、幻象读
- 《棍棍们的——许愿墙》
- XML学习
- java 关于区间树,KD树,线段树,伸展树,后缀树,红黑树的几段代码