muduo-01 IO的阻塞和非阻塞

IO的阻塞和非阻塞

  1. 网络IO阶段一
    数据准备分为阻塞状态和非阻塞状态。
    阻塞:调用IO方法的线程进入阻塞状态,有数据时被唤醒。
    非阻塞:不会改变线程的状态,通过返回值判断
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

int size = recv(sockfd, buf, 1024,0);
// 1.1 sockfd默认是阻塞的,如果没有数据可读,recv不会返回,线程会阻塞,等待数据到来。
// 1.2 有数据可读时,进入数据读写阶段二,返回读取数据的大小

/**非阻塞:根据返回值size分三种情况**/
/*正常的非阻塞返回,errno == EINTR ||(errno == EAGAIN)||errno == EWOULDBLOCK*/
if (size == -1 && errno == EAGAIN)
{
  /*正常的非阻塞返回*/
}
if (size == -1 && !(errno == EINTR ||(errno == EAGAIN)||errno == EWOULDBLOCK))
{
 /*出错*/
}

/*连接关闭*/
if(size == 0)
{
/*网络对端关闭连接*/……
}

/*有size大小的数据返回*/
if(size > 0 && errno = EGAIN)
{
//……
}
  1. 网络IO阶段二
    数据读写:IO的同步、异步
    (1)IO同步:数据到达用户态后,函数才返回。

同步阻塞I/O
用户线程发起 read 调用后就阻塞了,让出 CPU。内核等待网卡数据到来,把数据从网卡拷贝到内核空间,接着把数据拷贝到用户空间,再把用户线程叫醒。
同步非阻塞 I/O
用户线程不断的发起 read 调用,数据没到内核空间时,每次都返回失败,直到数据到了内核空间,这一次 read 调用后,在等待数据从内核空间拷贝到用户空间这段时间里,线程还是阻塞的,等数据到了用户空间再把线程叫醒。

/*TCP接收缓冲区的数据搬到buf,此处的buf由用户定义*/
char buf[1024] = {0};
int size = recv(sockfd, buf, 1024, 0);
if (size > 0)
{
	buf
}

(2)异步IO

异步 I/O
用户线程发起 read 调用的同时注册一个回调函数,read 立即返回,等内核将数据准备好后,再调用指定的回调函数sigio完成处理。在这个过程中,用户线程一直没有阻塞
异步关键词:通知
用户线程read 立即返回,等内核将数据准备好后,通知用户线程
buf是应用程序搬的,不用从TCP缓冲区搬过来
异步特点:效率高,编程复杂

aio_read()
aio_write()

举例:node.js基于异步非阻塞模式下的高性能服务器。

处理IO时,阻塞和非阻塞都是同步IO,只有使用了特殊的API才是异步IO。

Q:业务层面的一个逻辑处理,是同步还是异步?
同步:A操作等待B操作做完事情,得到返回值,继续处理;
异步:A操作告诉B操作它感兴趣的事件及通知方式,A操作继续执行自己的业务逻辑;等B监听到相应事件发生后,B会通知A,A开始相应的数据处理逻辑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值