首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux select 阻塞

Linux select 阻塞基础概念

select 是 Linux 系统中用于 I/O 多路复用的一个系统调用。它允许单个进程/线程处理多个 I/O 操作,通过检查多个文件描述符(例如套接字)的状态来决定是否可以进行 I/O 操作。当使用 select 时,如果没有文件描述符准备好,调用会阻塞,直到至少有一个文件描述符准备好为止。

优势

  1. 并发处理:可以在单个进程/线程中同时监视多个文件描述符,提高资源利用率。
  2. 灵活性:适用于各种 I/O 密集型任务,如网络服务器。

类型

  • 水平触发(Level Triggered):只要文件描述符处于就绪状态,每次 select 调用都会返回。
  • 边缘触发(Edge Triggered):仅在文件描述符状态从非就绪变为就绪时返回一次。

应用场景

  • 网络服务器:监听多个客户端连接,处理并发请求。
  • 实时系统:需要同时监控多个输入源。

遇到的问题及原因

问题select 调用长时间阻塞,影响程序响应性。

原因

  • 没有设置超时时间,导致无限期等待。
  • 文件描述符集合过大,检查效率低下。
  • 系统负载过高,导致文件描述符状态更新延迟。

解决方法

  1. 设置超时时间
  2. 设置超时时间
  3. 优化文件描述符集合
    • 定期清理不再需要的文件描述符。
    • 使用更高效的数据结构管理文件描述符集合。
  • 减少系统负载
    • 优化程序逻辑,减少不必要的计算。
    • 使用线程池或其他并发模型分担工作负载。

示例代码

以下是一个简单的 select 使用示例:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>

int main() {
    fd_set read_fds;
    struct timeval timeout;

    FD_ZERO(&read_fds);
    FD_SET(STDIN_FILENO, &read_fds);  // 监听标准输入

    timeout.tv_sec = 5;
    timeout.tv_usec = 0;

    int ret = select(STDIN_FILENO + 1, &read_fds, NULL, NULL, &timeout);
    if (ret == -1) {
        perror("select error");
        return 1;
    } else if (ret == 0) {
        printf("select timeout\n");
    } else {
        if (FD_ISSET(STDIN_FILENO, &read_fds)) {
            char buffer[1024];
            fgets(buffer, sizeof(buffer), stdin);
            printf("Received input: %s", buffer);
        }
    }

    return 0;
}

这个示例程序监听标准输入,如果在5秒内有输入,则读取并打印;否则,输出超时信息。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Linux下Socket编程(三)——非阻塞select的使用简介

简介 什么叫阻塞和非阻塞 select fd_set类型的变量相关宏定义 fcntl 实例 select总是返回1的问题。...使用Select就可以完成非阻塞(所谓非阻塞方式non- block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同...NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态。...的值大于0,这就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。...SELECT_fncl.png 示例 客户端创建socket 调用fcntl设置阻塞模式 调用connect开始连接。

4.3K10

一种理解同步异步,阻塞非阻塞,Linux IO 模型,select poll epoll 的方法

),select/poll/epoll这些概念困扰我许久,下面给出这一阶段我个人的理解。...Linux的五种IO模型 上一节中对同步/异步,阻塞/非阻塞的描述只能说能够恰好区分它们,如果不是在计算机领域而是生活中,道理也类似。...然而计算机中的某些专业术语又需要放在专门的情景中去看,例如下面将要提到的Linux IO模型,建议理解模型本身,而不是抠同步/异步与阻塞非阻塞的字眼,因为会发现就算是非阻塞模型也有阻塞的部分,同步IO与异步...模型的对比 Kernel有两个过程,等待数据准备好和拷贝数据到用户空间,用户程序的阻塞一般有两种情况,select的阻塞和socket IO的阻塞,5中IO模型的对比如下。...select int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds,struct timeval *timeout

6.9K10
  • linux阻塞与非阻塞(connect连接超时)

    只是当前连接还没有建立完整),所以我们可以在通过给select、pol或epoll设置等待时间,来等待这个connect的连接成功,从而进一步处理 如果非阻塞connect返回的错误不是EINPROGRESS...,代表就是connect系统调用本身出错了,那么就可以做一些相应的错误处理了 ③当非阻塞connect以EINPROGRESS错误返回之后,我们可以给select、pol或epoll设置等待时间,并将客户端封装在等待可写的结构中...: 1.首先,非阻塞的socket可能导致connect始终失败 2.其次,select对处于EINPROGRESS状态下的socket可能不起作用 3.最后,对于出错的socket,getsockopt...在有些系统(比如Linux)上返回-1,而在有些系统上(比如源自伯克利的UNIX)返回0 这些问题没有一个统一的解决办法 三、编码演示案例 #include #include select中等待非阻塞connect建立成功并且客户端fd变为可写的。

    6.5K10

    linux select函数详解

    http://blog.csdn.net/lingfengtengfei/article/details/12392449 在Linux中,我们可以使用select函数实现I/O端口的复用,传递给 select...(读,写,异常) 有了这些返回信息,我们可以调用合适的I/O函数(通常是 read 或 write),并且这些函数不会再阻塞....(5)structtimeval* timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态,第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态...第三,timeout的值大于0,这就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。...set,0,0,0)阻塞等待 (5)若fd=1,fd=2上都发生可读事件,则select返回,此时set变为0000,0011。

    5.3K20

    【Linux】深入 Linux 进程等待机制:阻塞与非阻塞的奥秘

    如果任意时刻调用wait/waitpid,子进程存在且正常运行,则可能阻塞。 如果不存在该进程,则立即出错放回。...sleep(5); exit(257); } else { //father int status = 0; pid_t ret = waitpid(-1,&status,0);//阻塞等待...{ //father int status = 0; pid_t ret = 0; do { ret = waitpid(-1,&status,WNOHANG);//非阻塞等待...3.解释堵塞与非堵塞 阻塞场景:打电话等朋友接听 你拨打朋友的电话,直到朋友接通之前你什么都做不了。这就像阻塞调用,你必须等着事情完成。...非阻塞场景:发消息等待回复 你给朋友发了个消息,等他们回你。你不用一直盯着手机看,而是可以去做别的事情,等收到消息后再查看。这就像非阻塞调用,你不需要等着完成才能做其他事情。

    13110

    Linux编程(阻塞的概念)

    阻塞。 好吧,再来一点营养。阻塞是啥意思呢? 就是水管堵住了!扭开水龙头没有水出来。...这个道理跟Linux下读取慢速设备(主要指管道和套接字)数据的情形非常相似,例如当我们在读取一个管道时,如果管道里面没有数据,那么我们什么都读不出来,于是就进入了所谓的“阻塞”状态了,说白了阻塞就是使得当前进程或者线程睡眠了的意思...那么再进一步,什么时候会阻塞呢?下面的表格简单描述了这些清空: ? 其中,读者指的是对管道文件拥有读权限的进程或线程(注意不是正在读),写者指的是对管道文件拥有写权限的进程或线程(注意不是正在写)。...除此之外,其实open()函数也会发生阻塞,比如用只读或者只写open一个管道文件的时候。因为一根只有出口或者只有入口的水管,是无法使用的呀!其实就是生活常识。嘿嘿!

    2.2K30

    从linux源码看socket的阻塞和非阻塞 顶

    从linux源码看socket的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。 大部分高性能网络框架采用的是非阻塞模式。...笔者这次就从linux源码的角度来阐述socket阻塞(block)和非阻塞(non_block)的区别。 本文源码均来自采用Linux-2.6.24内核版本。...\非阻塞状态 我们用fcntl修改socket的阻塞\非阻塞状态。...阻塞后什么时候恢复运行呢 情况1:有对应的网络数据到来 首先我们看下网络分组到来的内核路径,网卡发起中断后调用netif_rx将事件挂入CPU的等待队列,并唤起软中断(soft_irq),再通过linux...希望笔者这篇文章能帮助到阅读linux网络协议栈代码的人。

    3.6K20

    Linux下select使用陷阱

    Select函数使用简单,其工作原理大家通常也知道,但是在实际的使用过程中可能并没有严格遵守,而且确实也比较难以完全遵守,除非不使用它。...Select采用一个bit表,每个fd对应表中的一个bit位,宏FD_SETSIZE为表的大小,添加到fd_set中的fd值必须小于FD_SETSIZE,否则就会越界,假设有如下一段代码: fd_set...较容易发生在服务端程序中,因为服务端程序同一时刻的连接数很容易超过默认的FD_SETSIZE值,而服务端的代码可能是使用epoll使用的,所以它本身并不会存在问题,但是程序中可能还有个客户端,比如使用了select...来实现超时连接,这个时候问题就来了,当连接数超过FD_SETSIZE时,超时连接处的select调用就发生了越界,进程就会在某个可能完全不相干的地方crash,要定位这个问题的成本是很高的,不具备一定经验...那就是尽量不使用select,而应当使用更安全的poll函数来替代,因为poll使用的数组是调用者自己维护的,完全可以保证不越界。

    2K40

    Linux下select调用引发的血案

    Select函数使用简单,其工作原理大家通常也知道,但是在实际的使用过程中可能并没有严格遵守,而且确实也比较难以完全遵守,除非不使用它。...Select采用一个bit表,每个fd对应表中的一个bit位,宏FD_SETSIZE为表的大小,添加到fd_set中的fd值必须小于FD_SETSIZE,否则就会越界,假设有如下一段代码: fd_set...较容易发生在服务端程序中,因为服务端程序同一时刻的连接数很容易超过默认的FD_SETSIZE值,而服务端的代码可能是使用epoll使用的,所以它本身并不会存在问题,但是程序中可能还有个客户端,比如使用了select...来实现超时连接,这个时候问题就来了,当连接数超过FD_SETSIZE时,超时连接处的select调用就发生了越界,进程就会在某个可能完全不相干的地方crash,要定位这个问题的成本是很高的,不具备一定经验...那就是尽量不使用select,而应当使用更安全的poll函数来替代,因为poll使用的数组是调用者自己维护的,完全可以保证不越界。

    1.9K20

    同步、异步、阻塞、非阻塞

    阻塞与非阻塞   应用进程请求I/O操作时,如果数据未准备好,如果请求立即返回就是非阻塞,不立即返回就是阻塞。简单说就是做一件事如果不能立即获得返回,需要等待,就是阻塞,否则就可以理解为非阻塞。...非阻塞 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。...同步/异步与阻塞/非阻塞的组合 同步阻塞形式: 等待执行结果是一直等待,执行时线程挂起(未对fd 设置O_NONBLOCK 标志位的read/write 操作) 同步非阻塞形式:等待执行结果是一直等待,...执行时函数立即返回(对fd 设置O_NONBLOCK 标志位的read/write 操作) 异步阻塞形式:不是在处理消息时一直等待(通过状态、通知,或回调函数通知主调函数select ),而是在等待消息被触发时被阻塞...(线程挂起).如果select 函数,的最后一个timeout 参数为NULL,程序就会停止在select这里。

    3K40

    linux 网络编程 IO复用 select,poll ,epoll

    此时我们可以无阻塞地对该socket,并且读操作返回的字节数大于0 socket通信的对方关闭连接,此时读操作返回0 监听socket上有新的连接请求 socekt上有未处理的错误,此时我们可以使用getsockopt...此时我们可以无阻塞地写该socket,并且写操作返回的字节数大于0 socket的写操作被关闭。...对写操作被关闭的socket执行写操作将出发一个SIGPIPE信号 socket使用非阻塞connect连接成功或者失败之后 socket上有未处理的错误,此时我们可以使用getsockopt来读取和清除该错误...当timeout为-1时,poll调用将永远阻塞,直到某个事件发生。当timeout为0时,poll调用将立即返回。...---- 参考资料: 《Linux高性能服务器编程》

    2.6K20

    【Linux】高级IO --- 多路转接,select,poll,epoll

    参数,输入时,代表用户告知内核select监视等待fd时的方式,nullptr代表select阻塞等待fd就绪,当有fd就绪时,select才会返回,传0代表非阻塞等待fd就绪,即select只会遍历检测一遍底层的...fd,不管有没有fd就绪,select都会返回,传大于0的值,代表在该时间范围内select阻塞等待,超出该时间select直接非阻塞返回。...poll的返回值含义与select相同,大于0表示就绪的fd个数,等于0代表超时返回,小于0代表出错返回,timeout代表poll监视fd时的策略,大于0代表该数值范围内阻塞式监视,超过该数值则直接非阻塞返回...虽然说epoll是作了改进的poll,但在接口的使用和底层实现上,epoll和poll天差地别,在linux内核2.5.44版本时,就引入了epoll接口,而现在主流的linux内核版本已经是3点几了。...Linux、Unix、Windows 等 ---- poll缺点: (1)需要程序员自己维护一个第三方结构体数组来存储用户关心的fd及事件 (2)与select相同的是,用户仍然需要遍历整个数组来找出就绪的文件描述符

    36630
    领券