1, 关于阻塞的概念
阻塞(Block)这个概念。当进程调用一个阻塞的系统函数时,该进程被置于睡眠(Sleep)状态,这时内核调度其它进程运行,直到该进程等待的事件发生了(比如网络上接收到数据包,或者调用sleep指定的睡眠时间到了)它才有可能继续运行。与睡眠状态相对的是运行(Running)状态,在Linux内核中,处于运行状态的进程分为两种情况:
正在被调度执行。CPU处于该进程的上下文环境中,程序计数器(eip)里保存着该进程的指令地址,通用寄存器里保存着该进程运算过程的中间结果,正在执行该进程的指令,正在读写该进程的地址空间。
就绪状态。该进程不需要等待什么事件发生,随时都可以执行,但CPU暂时还在执行另一个进程,所以该进程在一个就绪队列中等待被内核调度。系统中可能同时有多个就绪的进程,那么该调度谁执行呢?内核的调度算法是基于优先级和时间片的,而且会根据每个进程的运行情况动态调整它的优先级和时间片,让每个进程都能比较公平地得到机会执行,同时要兼顾用户体验,不能让和用户交互的进程响应太慢。
2, IO模式设置
一般对于一个socket 是阻塞模式还是非阻塞模式有两种方式:
方法1、fcntl 设置;
flags = fcntl(sockfd, F_GETFL, 0); //获取文件的flags值。
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); //设置成非阻塞模式;
flags = fcntl(sockfd,F_GETFL,0);
fcntl(sockfd,F_SETFL,flags&~O_NUNBLOCK); //设置成阻塞模式;
方法2、recv, send 函数的最后有一个flag 参数可以设置成MSG_DONTWAIT
临时将sockfd 设置为非阻塞模式,而无论原有是阻塞还是非阻塞。
recv(sockfd, buff, buff_size,MSG_DONTWAIT); //非阻塞模式的消息发送
send(scokfd, buff, buff_size, MSG_DONTWAIT); //非阻塞模式的消息接受
3, 读(read/recv/msgrcv):
阻塞和非阻塞的区别在于没有数据到达的时候是否立刻返回.
read 也好,recv 也好只负责把数据从底层缓冲copy 到我们指定的位置.
阻塞情况下:
1、如果没有发现数据在网络缓冲中会一直等待,
2、当发现有数据的时候会把数据读到用户指定的缓冲区,但是如果这个时候读到的数据量比较少,比参数中指定的长度要小,read 并不会一直等待下去,而是立刻返回.
read 的原则,是数据在不超过指定的长度的时候有多少读多少,没有数据就会一直等待。所以一般情况下,我们读取数据都需要采用循环读的方式读取数据,因为一次read 完毕不能保证读到我们需要长度的数据,read 完一次需要判断读到的数据长度再决定是否还需要再次读取。
非阻塞情况下:
1、如果发现没有数据就直接返回,
2、如果发现有数据那么也是采用有多少读多少的进行处理.
所以read 完一次需要判断读到的数据长度再决定是否还需要再次读取。
4,写(send/write/msgsnd):
写的本质也不是进行发送操作,而是把用户态的数据copy 到系统底层去,然后再由系统进行发送操作,send,write返回成功,只表示数据已经copy 到底层缓冲,而不表示数据已经发出,更不能表示对方端口已经接管到数据.
阻塞情况下,write会将数据发送完。(不过可能被中断)
在阻塞的情况下,是会一直等待,直到write 完,全部的数据再返回.这点行为上与读操作有所不同。
非阻塞写的情况下,是采用可以写多少就写多少的策略.与读不一样的地方在于,有多少读多少是由网络发送的那一端是否有数据传输到为标准,但是对于可以写多少是由本地的网络堵塞情况为标准的,在网络阻塞严重的时候,网络层没有足够的内存来进行写操作,这时候就会出现写不成功的情况,阻塞情况下会尽可能(有可能被中断)等待到数据全部发送完毕, 对于非阻塞的情况就是一次写多少算多少,没有中断的情况下也还是会出现write 到一部分的情况.
分享到:
相关推荐
总结来说,理解I/O阻塞和非阻塞操作,掌握多路复用技术如select和pselect,以及熟悉UDP的广播和组播通信,对于开发高效、可靠的网络应用程序至关重要。这些知识和技巧是构建现代网络服务的基础,能帮助开发者优化...
对于高效的系统设计,理解并掌握阻塞I/O和非阻塞I/O是非常重要的。这两种I/O模型在处理数据传输时有着显著的区别,对程序性能和并发性有着深远的影响。 **阻塞I/O(Blocking I/O)** 阻塞I/O模型是最常见的I/O模式...
I/O模型主要有两种:阻塞(Blocking)和非阻塞(Non-blocking),这两种方式在处理设备请求时有着本质的区别。 阻塞I/O是Linux内核中最基本的I/O模型。当一个进程试图读取或写入一个尚未准备好的数据时,内核会将这...
同步和异步只关注客户端的调用机制,而阻塞和非阻塞则关乎服务端的处理方式。同步与异步的区分并不依赖于阻塞或非阻塞,它们可以结合使用。例如,客户端可以发起异步请求,然后服务端处理请求时可能采用阻塞或非阻塞...
Unix I/O系统是操作系统的核心部分,它提供了对文件和设备进行输入输出操作的接口。本文主要总结了Unix下的I/O模型及其相关系统调用。 在Unix中,每个进程都有一个打开文件描述符表,用于存储指向文件inode的指针和...
例如,对于高并发、低延迟的服务,可能更倾向于使用I/O多路复用和非阻塞I/O,而对性能有较高要求且数据流相对集中的情况,I/O聚集则更有优势。同时,正确管理和调度文件描述符,确保资源的有效利用,也是提升系统...
非阻塞I/O和I/O复用提高了并发性,但编程复杂度增加;信号驱动I/O在Windows中应用较少;异步I/O和完成端口则提供了最高的并发性和效率,但需要更复杂的编程技巧。 在Windows_Socket_IO模型的压缩包中,你可能会找到...
异步I/O处理的关键在于非阻塞和事件驱动。非阻塞I/O意味着即使没有数据可读,读取操作也不会挂起;事件驱动则是通过事件回调机制,当某个I/O操作完成时,系统会通知相应的处理函数。这种模型非常适合网络服务、...
5. **非阻塞I/O** 在传统的I/O模型中,读写操作通常是阻塞的,即在等待数据准备好或完成写入时,线程会被挂起。而在NIO中,通道和缓冲区支持非阻塞模式,当数据未准备好时,读写操作不会阻塞,而是立即返回,允许...
1. **初始化**:在类的构造函数中,可能包括创建套接字、设置套接字为非阻塞模式,以及配置重叠I/O的初始化工作。可能还会设置`OVERLAPPED`结构体,以及关联事件对象或窗口消息。 2. **接收和发送**:类可能提供了...
重叠I/O模型是一种非阻塞I/O模型,通过使用`OVERLAPPED`结构来异步执行I/O操作。这种方式非常适合高并发场景。 **示例代码:** ```c // 创建重叠结构 OVERLAPPED ovl; ZeroMemory(&ovl, sizeof(OVERLAPPED)); // ...
这可能包括选择合适的I/O模型(同步/异步,阻塞/非阻塞)、减少不必要的系统调用、利用多线程或异步操作等技术。 8. **设备文件和字符/块设备驱动** 在嵌入式Linux中,设备通常以文件形式存在。了解设备文件和如何...
3. **非阻塞I/O(NIO)**:Java NIO在Java 1.4引入,提供了异步I/O操作,可以处理多个连接,而无需为每个连接创建一个新的线程。关键类有Selector、Channel和Buffer,Selector可以监控多个通道的事件,Channel代表I/...
根据I/O模型的不同,可以将它们分为两大类:阻塞I/O和非阻塞I/O。这两种I/O模型对于系统的性能有着显著的影响,本文将深入探讨它们的原理、应用场景以及优缺点。 #### 二、阻塞I/O模型 ##### 2.1 定义 阻塞I/O是一...
非阻塞I/O(Non-blocking I/O),简称NIO,是Java 1.4引入的一个重要特性,主要由java.nio包提供。NIO的核心在于通道(Channels)和缓冲区(Buffers)。通道类似于流,但它们支持非阻塞读写,这意味着当数据不可用时...
非阻塞I/O可以提高服务器的并发性,但需要开发者处理复杂的同步问题,确保数据的完整性和正确性。 3. **I/O多路复用**:WINSOCK提供了`select()`和`poll()`函数来实现I/O多路复用。它们允许程序同时监视多个套接字...
这意味着开发者还需要配合其他非阻塞I/O技术,如`WSAAsyncSelect`或`WSAEventSelect`(在Winsock中),以实现完整的异步I/O模型。 总结来说,`select` I/O模型在客户端应用中扮演着关键角色,它帮助开发者高效地...
8. **非阻塞I/O**:与异步I/O类似,非阻塞I/O允许程序在等待I/O操作时不会被挂起,而是立即返回,通过轮询检查数据是否准备就绪。 总之,I/O交互支持库是软件开发中的基础工具,它简化了与系统进行数据交换的复杂性...
4. **I/O模式**:Linux支持多种I/O模式,如同步I/O、异步I/O、非阻塞I/O等,每种模式在处理数据传输时都有其优缺点。 5. **零拷贝(Zero-copy)技术**:为了解决传统I/O的拷贝开销,Linux引入了零拷贝技术。零拷贝...
重叠I/O是一种非阻塞I/O模型,它允许在I/O操作进行的同时,应用程序可以继续执行其他任务。这意味着多个I/O请求可以在同一时间进行,提高了系统资源利用率和程序响应速度。 2. **异步与同步**: 异步I/O与同步I/O...