io阻塞之同步/异步io(客户端中)

io阻塞之同步/异步io(客户端中)

               对于同一个fd,我一边往他里面输入(用fgets函数),一边让他接受服务器的数据,那么当我recv没有收到数据时他会一直等待,即阻塞在这里,那么他没办法接收来自fgets的输入数据。如图,我们的应用程序去调用这个recv这个函数,当调用的时候我们会进入内核层,内核层去检测我们套接字有没有传过来数据,如果没有数据,那么会一直等待,知道有数据来了,才把套接字里的数据返回到应用层。这就是阻塞的情况,那么我应该如何处理这种情况呢?
io阻塞之同步/异步io(客户端中) io阻塞之同步/异步io(客户端中)
我们可以把recv这个操作设置成非阻塞操作,那么如何设置呢?在recv函数中,最后一个参数是flag,这个参数可以设置成非阻塞。当设置成非阻塞是应用层与内核层的状态是图中的样子。当我们调用recv这个函数的时候,进入内核层后发现套接字没有数据,那么我们立即从内核层返回,而不是一直在内核层中等待。那么返回的数据是什么呢?我们如何让应用层知道我们没有读到数据呢?当没有读到数据的时候,从内核层返回的是一个标识符,这个标示符告诉应用层,我们内核没有数据。如此反复,当内核层中的套接字突然有数据的时候,我们就不在返回这样的标示符了,而是数据,那么这就是一种非阻塞的状态。
io阻塞之同步/异步io(客户端中) io阻塞之同步/异步io(客户端中)
代码中是这个样子,当我们没有读到的时候,continue,那么他会再次去调用recv函数去内核中读取,自动去读取这个操作是我们的系统自动去执行的,只要我们设置成非阻塞的方式,并且没有在代码中写return -1,那么我们会不断的去尝试读取数据。当然我们可以设置一个超时时间,当我们很长一段时间没有读取到数据的时候,我们会去返回,终止这样的操作。
但是,这种方式的弊端就是浪费资源,我们的操作不断的从内核转移到应用,再从应用转移到内核。我们可以找到更好的方法来代替这种。
我们可以采用一种信号通知的方式,我们不在应用层去检测我们套接字有没有接收到数据,我们将这个任务交给内核处理。那么,应该怎么做呢?我们可以在内核中注册一个sigio处理函数,当套接字接收到数据的时候,他会去通知我们应用层套接字收到了数据,这个时候我们再去调用recv函数去内核层中读取数据。这是一个比较好的方法。但是当我们需要处理大量的数据的时候,这种方式还是有一定的不善。
io阻塞之同步/异步io(客户端中)

接着上面内容,我们可以用异步io的方式。如图,我们运用一个函数aio_read,用这个函数去读取内核中套接字收到的数据,这个函数将读到的数据直接读到了我们的应用层。
io阻塞之同步/异步io(客户端中)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值