select函数使用细节
linux c/c++开发的同志们一定要掌握select函数,因为它简单高效。以下是本人开发中遇到的几个问题。
一、函数原型
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
参数解析:
nfds:最大监听fd数,一般是最大文件号加1
readfds:可读文件句柄集合。
writefds:可写文件句柄集合。
exceptfds:异常文件句柄集合。
timeout:NULL表示阻塞,非NULL可精确到微妙级别。
二、高级用途
1、监听句柄的读写事件
2、实现非租塞模型服务器
3、实现线程安全的sleep
三、使用实例
1.监听可读事件
int is_fd_can_read(int fd, long usec){struct timeval timeOut;bzero(&timeOut,sizeof(timeOut));timeOut.tv_sec = usec/1000000;timeOut.tv_usec = usec%1000000;fd_set rfds;FD_ZERO(&rfds);FD_SET(fd,&rfds);int rv=select(fd+1, &rfds, NULL, NULL, &timeOut); return rv>0?1:0;
}
注意:以上函数在fd取值在0到1152可正常监听可读事件,但是当fd等于1154时FD_SET() 则会发生“段错误”,原因在于select最大只能监听1024个句柄。看内核源码便了解:
static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
{unsigned long _tmp = fd / __NFDBITS;unsigned long _rem = fd % __NFDBITS;fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
}
#define __NFDBITS (8 * sizeof(unsigned long))
typedef struct {unsigned long fds_bits [__FDSET_LONGS];
} __kernel_fd_set;
#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS)
#define __FD_SETSIZE 1024
原因在于内核代码越界了,所以在fd超过1024则非常危险!
这个函数可以正常使用,但任然需要注意,select会被中断信号返回。但它仍然比sleep或者uleep函数在线程中安全。
2.监听可写事件
int is_fd_can_write(int fd, long usec){struct timeval timeOut;bzero(&timeOut,sizeof(timeOut));timeOut.tv_sec = usec/1000000;timeOut.tv_usec = usec%1000000;fd_set wfds;FD_ZERO(&wfds);FD_SET(fd,&wfds);int rv=select(fd+1,NULL,&wfds, NULL, &timeOut); return rv==1?1:0;
}
3.编写睡眠函数
void mySleepUsec(unsigned long usec){struct timeval timeOut;bzero(&timeOut,sizeof(timeOut));timeOut.tv_sec = usec/1000000;timeOut.tv_usec = usec%1000000;select(0, NULL, NULL, NULL, &timeOut);
}
四、建议
1.如果编写高并发服务器,请考虑epoll
2.不要妄想使用select监听消息队列的句柄,消息队列的句柄有可能远超了1024
3.如果阻塞时间需精确到微妙级以下,请使用pselect函数。
select函数使用细节相关推荐
- 深入研究socket编程(3)——使用select函数编写客户端和服务器
http://blog.csdn.net/chenxun_2010/article/details/50488394 首先看原先<UNIX网络编程--并发服务器(TCP)>的代码,服务器代 ...
- (二)TCP客户端/服务器通信------select函数
(一)select函数 该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒它.也就是说,我们调用select告知内核对哪些描述符(就读.写或异常 ...
- 29.Linux网络编程熟练掌握 TCP 状态张换图熟练堂握端口复用的方法了解半关闭的概念和实现方式了解多路10 转接模型熟练掌握 select 函数的使用熟练使用 fdset 相关函数的使用能够编写
把昨天的 第二天的内容说一下,复习一下,第二天 讲的东西不算多,但是有两个作业题来写一写, 大致浏览一下,三次握手 四次挥手的过程,大家有没有画一下? 能画出来吗?同学们,大家注意 这个写代码的时候其 ...
- R语言dplyr包使用select函数通过索引查询或者排除数据列实战(Select Columns by Index)
R语言dplyr包使用select函数通过索引查询或者排除数据列实战(Select Columns by Index) 目录
- socket通信时如何判断当前连接是否断开--select函数,心跳线程,QsocketNotifier监控socket...
client与server建立socket连接之后,如果突然关闭server,此时,如果不在客户端close(socket_fd),会有不好的影响: QsocketNotifier监控socket的槽 ...
- 关于select函数
1.阻塞模式下必须开多线程来解决阻塞问题,但是为每个socket开了多线程后,多线程的运行开销很大,速度超级慢. 如果,多线程的速度能跟得上,那是非常不错.但是事实上可能并非如此. 2.因此selec ...
- UNIX中的Select函数
表头文件 #i nclude<sys/time.h> #i nclude<sys/types.h> #i nclude<unistd.h> 定义函数 int sel ...
- select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET(转)
select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型, 原型: int select(int maxfd,fd_set *rds ...
- form select multiple 某个字段是数组_你知道什么是Select函数吗?
Select函数:允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒它. select man手册 举个栗子,我们可以调用Select,告诉内核仅仅在 ...
- linux 下 select 函数的用法
一.Select 函数详细介绍 Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect. accept.recv ...
最新文章
- ×××S:Reporting Services 技巧
- 帧布局(FrameLayout)及属性
- LOL快要凉?腾讯电竞应如何破除游戏生命周期诅咒
- MQTT协议笔记之mqtt.io项目TCP协议支持
- 数据结构与算法-python描述-单链表
- powerdesigner显示工具面板_photoshop教程-画笔工具预设与选项设置
- 用Java简便地去重+排序(洛谷P1059题题解,Java语言描述)
- 随机样本一致性:一种用于图像分析和自动制图的模型拟合模型(5)--(P4P的解析解)
- linux安装redis 和 使用
- 8.1 复用(组合/继承)
- go语言-csp模型-并发通道
- SUSE Linux上简单配置Samba服务器
- 神经网络入门之bp算法,梯度下降
- 用html做krc转换lrc的文件,来,教你怎么把酷狗音乐krc歌词转换成lrc歌词文件?
- Burp Suite —— 验证码识别、切换IP
- 编程之美学习笔记——数字相关(一)
- 树莓派cm4安装ax200驱动-wifi6
- Golang bytes源码分析
- 计算机系统结构知识总结,计算机基础知识总结
- 开机就是linux图形界面,怎么进入控制台,输命令? shell