FD_ISSET read 后程序被阻塞【原创】

author:张继飞

       FD_ISSET 是select()机制的一个成员而已,网上很多解释都是说FD_ISSET用来检测sockfd是否有动作,对应读,写,异常等,当select()只监听一个sockfd时,表面上看是这样,实际上 非也非也。

       FD_ISSET,见名思义,其实就是判断某个sockfd是否在这个fd set集合里。所以,当程序select()监听了多个sockfd后,若select()返回 >0 的话接下来所有的FD_ISSET 都会执行一遍。这样就容易引入问题了,当某个文件描述符fd打开方式是阻塞状态,但此时该fd并没有发生动作,执行read后便会进入阻塞。这就违背了我们设计程序的初衷,所以当使用select()监听多个文件描述符fd时,最好在打开设备时 将其设置为非阻塞状态 O_NONBLOCK。


select处在超时过程中,若程序被kill,则返回值<0。
`FD_ISSET` 是一个在 Unix 和类 Unix 系统(如 Linux、macOS)中的标准库函数,它通常与 `select()` 或 `poll()` 这样的 I/O 多路复用系统调用一起使用。这两个函数允许一个进程在多个文件描述符(file descriptors,通常是网络连接、文件或其他类型I/O)上等待事件。 `FD_ISSET(fd, &fds)` 函数的作用是检查给定的 `fd`(文件描述符)是否已设置在名为 `fds` 的布尔集合(通常是 `struct fd_set` 类型)中。`fd_set` 是一个用于表示一组文件描述符状态的数组,其中每个位对应一个文件描述符,0 表示未连接或无活动,1 表示有活动或已连接。 当调用 `select()` 或 `poll()` 时,它们会阻塞进程直到至少一个文件描述符的指定事件发生(比如数据可读、写入完成等)。`FD_ISSET` 会在每次循环后检查 `fds` 中的 `fd` 是否被设为活跃状态,从而决定进程是否需要继续等待,或者是否可以开始处理相应的 I/O 操作。 举个例子: ```c #include <stdio.h> #include <sys/select.h> int main() { int fd1 = open("file1.txt", O_RDONLY); // 打开文件 int fd2 = socket(AF_INET, SOCK_STREAM, 0); // 创建套接字 struct timeval tv; // 设置超时时间 FD_SET(fd1, &read_fds); FD_SET(fd2, &read_fds); while (1) { select(FD_SETSIZE, &read_fds, NULL, NULL, &tv); // 等待I/O事件 if (FD_ISSET(fd1, &read_fds)) { printf("Data ready on file1\n"); // 处理文件数据 } if (FD_ISSET(fd2, &read_fds)) { printf("Connection established on socket\n"); // 处理套接字连接 } } close(fd1); close(fd2); return 0; } ``` 在这个例子中,`FD_ISSET` 被用来检查 `read_fds` 集合中 `fd1` 和 `fd2` 是否有读取事件发生。如果有,程序将相应地处理文件或套接字的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值