天天看点

Linux IO模型漫谈(4)- 非阻塞IO1 fcntl函数2 非阻塞IO返回的错误3客户端代码

首先先说一下,阻塞io会在哪些地方阻塞住呢?输入操作read, 输出操作write,接受请求操作accept,发送请求操作connect,这四个地方阻塞进程。

非阻塞io的模型图示在前面的章节有讲过,它和阻塞io的最大区别就是:如果连接或者操作不能立即建立,那么连接的建立照样能发起,只是会返回一个错误信息。

同样,先说明几个用到的函数和操作:

其全名为”file control“。顾名思义,fcntl可以执行各种操作符控制操作。

第一个参数fd是文件描述符

第二个参数cmd是操作命令,比如设置套接字阻塞非阻塞的命令为f_setfl, 设置套接字属主的命令为f_setown

第三个参数以后,是操作命令的参数。比如设置非阻塞io型的f_setfl的参数为o_nonblock

所以设置非阻塞io的典型设置代码为:

flags = flags | o_nonblock;

fcntl(fd, f_setfl, flags);

对于不能满足的非阻塞io操作,system v会返回eagain错误,而源自berkeley的实现返回ewouldblock。大多数当前系统把这两个错误码定义为相同的值。

对不能满足的非阻塞io连接,系统会返回einprogress

按照非阻塞的定义,我们只需要将cli做下面修改:

运行方式:

1 server不启动

2 client启动,则会在connect这个地方进入无限循环。

好吧,是不是觉得有问题?

1 这种模型,客户端使用轮询不断调用io操作,那么,cpu就会一直用于轮询,造成cpu的浪费。

2 这种模型,代码量比阻塞的模型大很多

所以这个模型实际上是很少使用的。