阻塞(Block)
当进程调用一个阻塞的系统函数时,该进程被置于睡眠(Sleep)状态,这时内核调度其它进程运行,直到该进程等待的事件发生了(比如网络上接收到数据包,或者调用sleep 指定的睡眠时间到了)它才有可能继续运行。
睡眠状态相对的是运行(Running)状态,在Linux内核中,处于运行状态的进程分为两种情况:正在被调度执行和就绪状态。
假设同时监视多个设备,如果read(设备1)是阻塞的,那么只要设备1没有数据到达就会一直阻塞在设备1的read调用上,
即使设备2有数据到达也不能处理,使用非阻塞I/O就可以避免设备2得不到及时处理。
非阻塞
在open 一个设备时指定了O_NONBLOCK 标志,read / write 就不会阻塞。
以read 为例,如果设备暂时没有数据可读就返回-1,同时置errno 为EWOULDBLOCK(或者EAGAIN,这两个宏定义的值相同),表示本来应该阻塞在这里(would block,虚拟语气),事实上并没有阻塞而是直接返回错误,调用者应该试着再读一次(again)。
这种行为方式称为轮询(Poll),调用者只是查询一下,而不是阻塞在这里死等,这样可以同时监视多个设备。
非阻塞I/O有一个缺点,如果所有设备都一直没有数据到达,调用者需要反复查询做无用功,如果阻塞在那里,操作系统可以调度别的进程执行,就不会做无用功了。
select(2) 函数可以阻塞地同时监视多个设备,还可以设定阻塞等待的超时时间,从而圆满地解决了这个问题。
当I/O有数据到达,就会产生一个中断,让阻塞的线程继续运行。
以下是单片机串口发送数据的流程
你要发送的数据,经串行口发送后,SCON中的TI会置1,这时候就会有串行口中断,通知单片机数据已经发送成功,单片机就可以进入串行口中断程序(汇编中入口地址0023H),
这时候你就可以再一次发送数据,也就是将数据写到SBUF中,发送后中断返回,等到发送成功后会再一次产生串行口中断,这时你就可以再次进入中断处理程序,发送数据。
流程是: (主程序中)发送数据--等待中断--发送成功产生中断--进入中断清除TI,再次发送--中断返回---等待中断---发送成功产生中断--进入中断清除TI,再次发送。。。。 循环而已
一,read 函数从打开的设备或文件中读取数据
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0
读上来的数据保存在缓冲区buf 中,同时文件的当前读写位置向后移。注意这个读写位置和使用C标准I/O库时的读写位置有可能不同,这个读写位置是记在内核中的,
而使用C标准I/O库时的读写位置是用户空间I/O缓冲区中的位置。
二,write 函数向打开的设备或文件中写数据
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
返回值:成功返回写入的字节数,出错返回-1并设置errno
相关推荐
本文档详细介绍了 Linux 客户端 Socket 非阻塞 connect 编程的实现方法和原理。非阻塞 connect 是一种高效的网络编程技术,能够提高程序的性能和可靠性。 一、非阻塞 connect 的应用场景 非阻塞 connect 主要应用...
阻塞与非阻塞IO的选择取决于具体的应用场景和性能需求。阻塞IO虽然可能导致进程暂时停滞,但在资源密集型操作中能更高效地利用CPU资源;而非阻塞IO更适合于资源有限、响应时间敏感的场合,尽管它可能引入额外的CPU...
在编写设备驱动时,理解这些I/O模型的工作原理和优缺点至关重要。开发者需要根据设备的特性、系统的资源约束以及应用程序的需求来选择合适的方式。例如,对于磁盘I/O,由于其天然的延迟,非阻塞可能更合适;而对于...
本文主要探讨的是从源码角度理解阻塞和非阻塞Socket的区别,特别是在Linux 2.6.24内核版本中的实现。阻塞和非阻塞模式是Socket编程中的重要概念,它们决定了程序在进行读写操作时的行为。 首先,创建一个Socket是...
学习这个源码,开发者可以深入了解非阻塞I/O的工作原理,掌握在Linux环境下如何编写高效的I/O密集型程序。这对于开发网络服务器、数据库连接管理或其他需要处理大量并发连接的应用来说,是至关重要的技能。通过实践...
非阻塞UDP服务器是一种高效且...非阻塞UDP服务器的实现涉及操作系统底层的网络编程,理解其工作原理并正确应用,对于构建高性能、高并发的网络应用至关重要。在实际开发中,还需要结合具体业务需求和性能指标进行优化。
### IO模型中的阻塞模型和非阻塞模型 在计算机科学领域中,输入/输出(Input/Output,简称IO)模型对于操作系统与应用程序之间的交互至关重要。根据数据读写操作是否可以立即返回,IO模型通常被划分为阻塞式...
首先,让我们深入理解非阻塞模式的工作原理。在非阻塞模式下,当调用read()或write()函数尝试从Socket读取或写入数据时,如果数据尚未准备好,这些函数不会阻塞,而是立即返回一个错误代码(通常为EAGAIN或...
总结来说,非阻塞模式网络通信模型在Linux中通过`select`或类似机制实现了异步I/O,提高了程序的并发性能。它允许程序在等待网络事件时执行其他任务,从而避免了资源的浪费。在实际应用中,这种模型常用于高并发...
本文将深入探讨如何在Linux环境下实现多线程的阻塞模式socket编程,以及它的工作原理和应用价值。 首先,理解“阻塞”和“非阻塞”模式。在Linux的socket编程中,阻塞模式是指当一个套接字(socket)调用如recv或...
### 阻塞与非阻塞IO详解 #### 一、阻塞型I/O **1.1 阻塞I/O的概念和意义** 在计算机操作系统中,I/O(输入/输出)...在设计设备驱动或应用程序时,理解这些模型的工作原理和特性对于构建高效稳定的系统至关重要。
**调度算法**:Linux采用多种调度策略,包括抢占式调度和非抢占式调度,以满足不同场景的需求。比如,实时调度用于保证关键任务的执行,而CFS(Completely Fair Scheduler)则确保所有进程都能公平地获得CPU时间。 ...
### Linux原理与应用知识点概述 #### 一、硬件基础 **1.1 CPU** - **定义**: 中央处理器(Central Processing Unit),是计算机的核心部件之一,负责执行指令。 - **功能**: 解释计算机指令以及处理计算机软件传来...
本教程将详细解释Linux中的非阻塞TCP服务端与客户端的实现,以及如何通过源码来理解其工作原理。 非阻塞I/O在Linux中是一个重要的特性,它允许进程在没有准备好数据时继续执行其他任务,而不是等待数据的到来。这种...
在Linux系统中,非阻塞I/O通常通过select、poll、epoll等系统调用来实现。 首先,我们来看非阻塞I/O的基本概念。在传统的阻塞I/O模型中,当进程发起一个I/O请求后,如果数据尚未准备好,内核会将进程挂起,直到数据...
6. **阻塞和非阻塞I/O**:阻塞I/O会暂停进程直到数据可用,而非阻塞I/O不会等待,如果数据未准备好,它会立即返回错误。在读取终端时,阻塞和非阻塞模式有明显区别,非阻塞模式可以防止进程因等待输入而被长时间挂起...
不可靠信号(如SIGKILL和SIGSTOP)一旦发出就立即生效,无法被阻塞或忽略,而可靠信号(如SIGINT和SIGTERM)可以被排队,允许进程有适当的机会处理它们。 在Linux内核中,信号与进程结构紧密相关,每个进程都有一个...
5. 文件I/O操作:这是Linux系统编程的重要部分,包括文件的打开、关闭(open/close)、读写(read/write)、阻塞与非阻塞操作、文件位置操作(lseek)以及文件控制(fcntl)和IO控制(ioctl)。文件描述符和最大打开...
- **I/O操作**:阻塞和非阻塞I/O,异步I/O,I/O复用(`select`、`poll`、`epoll`)。 - **网络编程**:套接字API,TCP/IP协议栈,客户端和服务端编程,错误处理和调试技巧。 这两份文档将帮助读者深入理解Linux...