linux c中select使用技巧——计时器(转)
2017-08-23 17:39
239 查看
通过本文你会了解到:
1. select()原型及参数说明
2. select()应用情景
3. select()注意事项
4. select()作定时器
原型
1 int select(int nfds, fd_set *readfds, fd_set *writefds, 2 fd_set *exceptfds, struct timeval *utimeout);
参数说明
readfds,
writefds,
exceptfds为所要监听的三个描述符集:
——
readfds监听文件描述符是否可读,不监听可以传入
NULL
——
writefds监听文件描述符是否可写 ,不监听可以传入
NULL
——
exceptfds监听文件描述符是否有异常,不监听可以传入
NULL
nfds是
select()监听的三个描述符集中描述符的最大值+1
timeout设置超时时间
更详细信息请参考译文linux-select()
应用情景
select()函数的重点在于它可以同时监控多个描述符(一般最大为1024),并且在描述符集中没有可操作的描述符时会进入睡眠状态。 实际应用中,若需要同时处理多个描述符的读写时,如果只是创建了一系列的
read()和
write()就会导致在有些描述符没有准备好读写时而被阻塞,这样当然不是我们期望的,因此这时就需要应用
select()。
注意事项
这段是
select()使用必须要了解和掌握的知识点,建议认真阅读,同时可以结合后续的一些实例做分析,相信你一定能掌握
select()使用方法。
nfds必须被正确设置,一般取描述符集中描述符的最大值并加1。
在非必须的情况下,尽量使用不超时的
select(),即将
utimeout参数设置为
NULL。
1 /*参数 timeout 置为 NULL*/ 2 select(nfds, &readfds, &writefds, &exceptfds, NULL);
timeout的值必须在每次
select()之前重新赋值,因为操作系统会修改此值。
1 while(1) { 2 timeout.tv_sec = 1; 3 timeout.tv_usec = 0; 4 select(nfds, &readfds, &writefds, &exceptfds, &timeout); 5 }
由于
select()会修改字符集,因此如果
select()调用是在一个循环中,则描述符集必须被重新赋值。
1 /*以read操作为例*/ 2 while(1) { 3 FD_ZERO(&readfds); 4 FD_SET(fd, &readfds); 5 select(nfds, &readfds, NULL, NULL, NULL); 6 }
函数
read(),
write(),
recv(),
send()以及
select()可能会返回-1并且errno置位为EINTR,或这errno被赋值为EAGAIN(EWOULDBLOCK),这种情况需要被正确处理。如果程序中不接收任何信号,则不会得到EINTR。如果程序设为阻塞I/O,则不会收到EAGAIN。
1 /*一般只需对EINTR进行处理就可以了,例子如下*/ 2 while(1) { 3 ret = select(nfds, &readfds, NULL, NULL, NULL); 4 if(ret == -1 && errno == EINTR) 5 continue; 6 }
当
read(),
write(),
recv()和
send()返回0时建议关闭描述符并在字符集中移除此描述符(不关闭描述符并移除的话可能会导致未知错误,还是对此情况处理的好)。
定时器
在没有usleep函数的系统中,可以应用select来实现,下例中实现了0.2秒的延时:
1 struct timeval tv; 2 tv.tv_sec = 0; 3 tv.tv_usec = 200000; /* 0.2 秒*/ 4 select(0, NULL, NULL, NULL, &tv);
相关文章推荐
- linux c中select使用技巧
- linux c中select使用技巧
- REUSE_ALV_POPUP_TO_SELECT的使用技巧
- webuploader、select2、validate、my97插件使用技巧
- [技巧]go语言使用select{}产生随机数
- Go语言技巧:使用select{}阻塞main函数
- select2插件-简单技巧使用心得
- [技巧]go语言使用select{}阻塞main函数和for range 做定时器服务
- Select2的Tags使用技巧
- Oracle常用SQL技巧SELECT子句中避免使用
- hive中select中DISTINCT的技巧和使用
- 关于select中DISTINCT的技巧和使用
- 关于select中DISTINCT的技巧和使用
- ThinkPHP 模型方法 getField() 和 select() 使用技巧
- sql server 2000更新技巧&select 查询中带参数,游标中使用exec
- 关于select中DISTINCT的技巧和使用
- 关于select中DISTINCT的技巧和使用
- 使用bootstrap select2 的下拉框组件时候的一些技巧
- CString的Format方法使用技巧
- VMWare 安装使用技巧