Chinaunix首页 | 论坛 | 博客
  • 博客访问: 387264
  • 博文数量: 75
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 645
  • 用 户 组: 普通用户
  • 注册时间: 2015-06-03 18:24
文章分类

全部博文(75)

文章存档

2019年(1)

2018年(20)

2017年(14)

2016年(10)

2015年(30)

分类: LINUX

2016-01-28 23:03:49

    在使用select函数时,就免不了要遇到fd_set结构体。那我们就来深入研究下fd_set的结构体!

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
首先,我们来看下下面几个函数!


这几个函数都有用到fd_set类型的数据,我们就会想这个到底是种什么类型的数据!下面来一步步来看个究竟


在/usr/include/sys/select.h中

点击(此处)折叠或打开

  1. typedef long int __fd_mask;


  2. /* It's easier to assume 8-bit bytes than to get CHAR_BIT. */
  3. #define __NFDBITS (8 * (int) sizeof (__fd_mask))
  4. #define __FDELT(d) ((d) / __NFDBITS)
  5. #define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))

  6. /* fd_set for select and pselect. */
  7. typedef struct
  8.   {
  9.     /* XPG4.2 requires this member name. Otherwise avoid the name
  10.        from the global namespace. */
  11. #ifdef __USE_XOPEN
  12.     __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
  13. # define __FDS_BITS(set) ((set)->fds_bits)
  14. #else
  15.     __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
  16. # define __FDS_BITS(set) ((set)->__fds_bits)
  17. #endif
  18.   } fd_set;

  19. /* Maximum number of file descriptors in `fd_set'. */
  20. #define FD_SETSIZE __FD_SETSIZE   //__FD_SETSIZE等于1024

  21. /* Access macros for `fd_set'.  */
  22. #define FD_SET(fd, fdsetp)      __FD_SET (fd, fdsetp)
  23. #define FD_CLR(fd, fdsetp)      __FD_CLR (fd, fdsetp)
  24. #define FD_ISSET(fd, fdsetp)    __FD_ISSET (fd, fdsetp)
  25. #define FD_ZERO(fdsetp)         __FD_ZERO (fdsetp)
从上面的代码中简化下来,其实可以改成
typedef struct{
    long int fds_bits[32];
}fd_set;
其实fd_set就是一个long int类型的数组。因为每一位可以代表一个文件描述符。所以fd_set最多表示1024个文件描述符!

在 /usr/include/bit/select.h中

点击(此处)折叠或打开

  1. # define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))
  2. # define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d))
  3. # define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))

通过查看这几个源码,我们就可以知道这几个函数的实现!现在我就跟踪下FD_SET(fd, fdsetp)这个函数的实现

  1. #define FD_SET(fd, fdsetp)      __FD_SET (fd, fdsetp)

  1. # define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))

  1. # define __FDS_BITS(set) ((set)->__fds_bits)

  1. #define __FDELT(d) ((d) / __NFDBITS)

  1. #define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))


将上面的函数化简下,就可以得到

#define FD_SET(fd,fdsetp)  fdsetp->__fds_bits[fd/32] |= (long int)1<<(d%32)

也就是将相应的位进行置位!


下面我们通过代码来对我们的结果进行验证!

点击(此处)折叠或打开

  1. #include <sys/select.h>

  2. #include <sys/time.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include <stdio.h>

  6. int main(void)
  7. {
  8.     fd_set set;

  9.     FD_ZERO(&set);

  10.     int i;
  11.     for(i = 0;i < 32;i++)
  12.     {
  13.         printf("set.__fds_bits[%d]:%ld\t",i,set.__fds_bits[i]);
  14.     }
  15.     printf("\n/////////////////////////////////////////\n");
  16.     FD_SET(10,&set);
  17.     for(i = 0;i < 32;i++)
  18.     {
  19.         printf("set.__fds_bits[%d]:%ld\t",i,set.__fds_bits[i]);
  20.     }
  21.     
  22.     printf("\n/////////////////////////////////////////\n");
  23.     FD_ZERO(&set);
  24.     FD_SET(32,&set);
  25.     for(i = 0;i < 32;i++)
  26.     {
  27.         printf("set.__fds_bits[%d]:%ld\t",i,set.__fds_bits[i]);
  28.     }
  29. }
FD_SET(10,&set);将set的第十位置一,也就是set.__fds_bits[0]为1024!
FD_SET(32,&set);将set的第32位置一,也就是set.__fds_bits[1]为1
执行结果如下:




























阅读(5373) | 评论(0) | 转发(0) |
0

上一篇:linux的时间函数

下一篇:linux环境变量

给主人留下些什么吧!~~