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 到一部分的情况.
分享到:
相关推荐
java阻塞i/o与非阻塞i/o控制,使开发者编写更好的i/o程序
I/O阻塞与非阻塞操作应用 socket多路复用技术socket信号驱动UDP广播与组播通信
主要介绍了详解socket阻塞与非阻塞,同步与异步、I/O模型,socket网络编程中的同步,异步,阻塞式,非阻塞式,有何联系与区别,本文将详细讲诉。
linux 设备驱动开发详解,宋宝华,人民邮电出版社
同步异步,阻塞非阻塞,I/O学习总结的思维导图,需要结合Richard Stevens的书来学习
计算机二级c语言真题后端开发 技术关键词: Node.js与Express框架 内容关键词: 事件驱动的非阻塞I/O ...Node.js的非阻塞I/O和事件驱动模型,使其非常适合处理高并发的实时应用,如在线聊天、实时数据流等。
nuix下的I/O编程机制,阻塞、非阻塞等
写的是Linux设备驱动中的阻塞和非阻塞I/0,何谓阻塞与非阻塞I/O?简单来说是对I/O操作的两种不同的方式,驱动程序可以灵活的支持用户空间对设备的这两种访问方式。 一、基本概念: 阻塞操作:是指在执行设备...
阻塞I/O和非阻塞I/O的区别在于系统在输入与输出的期间,能不能接收输入。 举个例子:餐厅服务员招待客人 阻塞I/O:餐厅有多个服务员(多线程),一个服务员对应一个客人,客人从点菜到点菜结束的期间,服务员都会被...
采用重叠I/O方式实现的socket网络编程,异步非阻塞方式,代码效率比阻塞式的socket编程方式高。实现了TCP server,TCP client,UDP server,UDP client,四种方式可选,可以使用在各种场合用于监控网络数据。本程序...
主要介绍了Java 非阻塞I/O使用方法,文中涉及非阻塞I/O的简介,同时向大家展示了利用非阻塞I/O实现客户端的方法,需要的朋友可以参考下。
O:阻塞,非阻塞和异步 介绍 在描述I / O时,术语“非阻塞”和“异步”通常可以互换使用,但是它们之间存在显着差异。 本文描述了Java中非阻塞和异步套接字I / O操作之间的理论和实践差异。 套接字是通过TCP和UDP...
写的是Linux设备驱动中的阻塞和非阻塞I/0,何谓阻塞与非阻塞I/O?简单来说是对I/O操作的两种不同的方式,驱动程序可以灵活的支持用户空间对设备的这两种访问方式。 一、基本概念: 阻塞操作 : 是指在执行设备...
阻塞和非阻塞I/O在设备驱动中的应用 目标 理解阻塞、非阻塞、轮询三种I/O模型 掌握阻塞I/O在驱动程序中的使用 掌握驱动和应用程序中的轮询编程 第一章:阻塞型I/O 第二章:轮询操作(I/O复用) 第三章:三种I/O模型...
java开发非阻塞i/o很好用的框架,简单便利,这个是稳定版1.1.7
Linux环境下的非阻塞式I/O的编程方法
非阻塞模式:执行I/O操作时,Winsock函数会返回并交出控制权。这种模式使用 起来比较复杂,因为函数在没有运行完成就进行返回,会不断地返回 WSAEWOULDBLOCK错误。但功能强大。 为了解决这个问题,提出了进行I/O操作...
阻塞和非阻塞又有什么区别?本文先从 Unix 的 I/O 模型讲起,介绍了5种常见的 I/O 模型。而后再引出 Java 的 I/O 模型的演进过程,并用实例说明如何选择合适的 Java I/O 模型来提高系统的并发量和可用性。,需要的...
非阻塞 I/O 执行的系统调用总是立即返回,不管事件是否已经发生。如果事件没有立即发生,这些系统调用返回 -1,然后设置 errno,应用程序需要根据返回的 errno 进行相应的处理。 I/O 复用 I/O 复用是指,应用程序...