Linux下select()的疑惑。

2024-04-08 09:18
文章标签 linux select 疑惑

本文主要是介绍Linux下select()的疑惑。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在一次使用select()的过程中,
发现select的value of return及循环调用select()其中timeout的值似乎有些超出预期,
于是查了一下,发现有些地方真的没有注意到。

Linux man manual:
/* According to POSIX.1-2001 */
       #include <sys/select.h>

       /* According to earlier standards */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

       #include <sys/select.h>
       int pselect(int nfds, fd_set *readfds, fd_set *writefds,
                   fd_set *exceptfds, const struct timespec *timeout,
                   const sigset_t *sigmask);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       pselect(): _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600

对于select()的返回值判断,还是依据FD_ISSET()的返回值来判断是否可以接收。
APUE 2 描述的select的返回值
关于select的返回值有三种可能:
1、返回值-1,表示出错。
2、返回值0,表示描述符没有准备好。若指定的描述符没有准备好,且指定的时间超时,返回0.同时,描述符集被清零。
3、正返回值,表示已经准备好的描述符数,该值是三个描述符集中已经准备好的描述符数之和,如果统一描述符的写和读都已准备好,则返回值中将为2,。
Linux man manual:
uccess,  select() and pselect() return the number of file descrip-
       tors contained in the three returned  descriptor  sets  (that  is,  the
       total  number  of  bits  that  are set in readfds, writefds, exceptfds)
       which  may be zero if the timeout expires  before  anything  interesting
       happens.  On error, -1 is returned, and errno is set appropriately; the
       sets and timeout become undefined, so do not  rely  on  their  contents
       after an error.
关于这个要十分注意,select()如果超时,是可能返回zero,而不是标准规定,如此如果超时根据等于零判断,有可能会出现问题。
就是超时了,但是仍然返回正确。

关于 struct timeval *timeout
APUE2描述的返回值:
timeout->tv_sec !=0 || timeout->tv_usec != 0
等待指定的秒数和微秒数。当指定的描述符之一已经准备好,或者指定的时间值已经超过时,立即返回。如果超时时,还没有一个描述符准备好,则返回值是0.同时,这种等待可能被捕捉到的信号打断。

这里如果有准备好的描述符时,返回值是多少并没有提及。
在linux的man manual中
On  Linux,   select() modifies timeout to reflect the amount of time not
       slept; most other implementations do not do this.   (POSIX.1-2001  per-
       mits either behavior.)  This causes problems both when Linux code which
       reads timeout is ported to other operating systems, and  when  code  is
       ported  to Linux that reuses a struct timeval for multiple select()s in
       a loop without reinitializing it.   Consider  timeout  to  be  undefined
       after select() returns.
即由于Linux中的select() modifies timeout,这样就造成了timeout可能是未知的。所以最后一句指明,在调用select()后,timeout的知就是未定义的。

在自己使用的ARM-Linux中,
timeout的返回值如下:
struct timeval的输入参数,被select修改了。
超时时的的time返回值:
sTv.tv_sec1: 20
sTv.tv_sec2: 0

未超时时的返回值:
sTv.tv_sec1: 20
sTv.tv_sec2: 18
由此观察可知,
超时时返回零,未超时时返回,剩余的时间。

所以,对于使用select时timeout的后续使用要小心一些。
同时pselect()对timeout作了const限定,它的值是不会被修改,如果循环使用还是pselect 更合适。

这篇关于Linux下select()的疑惑。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/885178

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Go中select多路复用的实现示例

《Go中select多路复用的实现示例》Go的select用于多通道通信,实现多路复用,支持随机选择、超时控制及非阻塞操作,建议合理使用以避免协程泄漏和死循环,感兴趣的可以了解一下... 目录一、什么是select基本语法:二、select 使用示例示例1:监听多个通道输入三、select的特性四、使用se

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

linux安装、更新、卸载anaconda实践

《linux安装、更新、卸载anaconda实践》Anaconda是基于conda的科学计算环境,集成1400+包及依赖,安装需下载脚本、接受协议、设置路径、配置环境变量,更新与卸载通过conda命令... 目录随意找一个目录下载安装脚本检查许可证协议,ENTER就可以安装完毕之后激活anaconda安装更