内容: 记录一下select的一些其他的用法
IO复用的方法可以有:select,poll,epoll
而其中的select除了做IO复用之外,还可以有其它有趣的用法:
1、做为定时器使用
2、检测fd是否有效(将fd注册可写,若select返回可写结果集中没有此fd,则该与fd对应的连接有问题)
select作为定时器使用可以提供比sleep更高的精度:
//秒级别定时器
void my_sleep(unsigned int time)
{
struct timeval tv;
tv.tv_sec = time;
tv.tv_usec = 0;
select(0, NULL, NULL, NULL, &tval);
}
//毫秒级别定时器
void my_sleep(unsigned int time)
{
struct timeval tv;
tv.tv_sec = time / 1000;
tv.tv_usec = (time % 1000) * 1000;
select(0, NULL, NULL, NULL, &tval);
}
//微秒级别定时器
void my_sleep(unsigned int time)
{
struct timeval tval;
tval.tv_sec = time / 1000000;
tval.tv_usec = time % 1000000;
select(0, NULL, NULL, NULL, &tval);
}
为什么sleep不够精确:
sleep(XX)的作用:告诉操作系统,在未来的XX这段时间内不再参与CPU竞争。直到XX这么长时间过去后。
这时候若另外的线程正在使用CPU,并且也不能马上被调度切换,那么这时操作系统
是不会重新分配CPU的,需要等到那个线程挂起或结束;而且有进程间有高低优先级,
普通进程与实时进程,如果有更高优先级或者实习进程需要马上被调度,那么sleep
的进程不一定能在XX这段时间后马上被调度。
sleep(XX)的原理:
1、挂起进程
2、设置一个定时器。
3、超时后定时器会触发,内核收到中断后将线程标志为就绪而进入就绪队列等待调度
sleep(XX)不够精确原因:受当前CPU忙碌程度影响,可能准确,也可能延迟。因此整体不够精确,且sleep
在linux下的实现单位是秒,是一个比较大粒度的单位,因此实际误差会更大。
大四学生一枚,如果文章有错误的地方,欢迎在下方提出,每条评论我都会去认真看并回复,同时感谢指正的前辈。有喜欢C/C++,linux的同学欢迎私信一起讨论学习。