linux第7天 I/O的五种模型, select
服务器端避免僵尸进程的方法: 1)通过忽略SIGCHLD信号,解决僵尸进程 signal(SIGCHLD, SIG_IGN) |
2)通过wait方法,解决僵尸进程 signal(SIGCHLD, handle_sigchld); wait(NULL) |
3)通过waitpid方法,解决僵尸进程 signal(SIGCHLD, handle_sigchld); wait(-1, NULL, WNOHANG) |
TCP/IP的11种状态
建立连接时, TCP B先处于listen状态, A 发送一个请求SYN a, B接受到进行连接,然后发送一个b和a + 1,其中b代表B请求A的连接,a + 1代表回应A请求成功.最后A回应给B a+1,代表B的请求成功
看上去有点抽象,举个形象的例子,A代表男孩,B代表女孩 男孩叫女孩开房,女孩回复说好的,男孩就进入ESTABLISHED状态,女孩问男孩是不是喜欢自己,男孩说是,女孩子进入ESTABLISHED状态.
以上就是三次握手的过程.
断开连接时,A 主动关闭套接字,会给B发送一个FIN x字段(0个字节,B一般可以通read的返回值来判断A是否关闭套接字),B收到之后TCP会悄悄地回应A一个x + 1,代表B已经收到A的退出消息,A处于FIN_WAIT_2状态,B处于CLOSE_WAIT状态,
如果B此时也关闭套接字,那么A将会处于TIME_WAIT状态,一段时候会消除.B也消除.
形象的例子,男女朋友分手,男人说我想分手,并把女人送给男人的东西还给女人,女人收下后说我知道了.这时男人处于FIN_WAIT_2状态(半连接),女人处于CLOSE_WAIT状态(等待下决心彻底放下男人),
女人经过思想斗争后,对男人说,我同意分手,并把男人送给女人的东西还给男人,这时,男人处于TIME_WAIT状态,一直目送女人离开.
理解0:什么是主动套接字,什么是被动套接字?服务端口在listen前是主动套接字,之后变成被动套接字
理解1:为什么TCP/IP要三次握手,和四次断开?因为tcp/ip是可靠连接,频繁的握手与断开是为了信息稳定.
理解2:客户端状态向前推进过程,服务器端状态向前推进过程
理解3:执行主动关闭的那一端,进入TIME_WAIT状态
理解4:TIME_WAIT 时间是多长2MSL (2倍的最大生命期时间)
原因:(ACK y+1)如果发送失败可以重发。
服务器端处于closed状态,不等于客户端也处于closed状态。。
理解5:图上几种状态,还有一种CLOSING状态
两端同时关闭 将产生closing状态,最后双方都进入TIME_WAIT状态。
如果对方socket已关闭,已方再发写数据,则会产生SIGPIPE信号
SIGPIPE信号会让进程终止(man 7 signal,阅读SIGPIPE默认ACT)
往一个已经接收FIN的套接中写是允许的,接收到FIN仅仅代表对方不再发送数据。
在收到RST段之后,如果再调用write就会产生SIGPIPE信号,对于这个信号的处理我们通常忽略即可。
signal(SIGPIPE, SIG_IGN);
close终止了数据传送的两个方向.
shutdown可以有选择的终止某个方向的数据传送或者终止数据传送的两个方向。
shutdown how=1就可以保证对等方接收到一个EOF字符,而不管其他进程是否已经打开了套接字。而close不能保证,直到套接字引用计数减为0时才发送。也就是说直到所有的进程都关闭了套接字。
阻塞I/O
说明1:当上层应用app1调用recv系统调用时,如果对等方没有发送数据(缓冲区没有数据),上层应用app1将阻塞(默认行为,被linux内核阻塞);
说明2:当对等方发送了数据,linux内核recv端缓冲区,有数据后,内核会把数据copy给用户空间。然后上层应用app1解除阻塞,执行下一步操作。
非阻塞I/O
说明1:上层应用程序app2将套接字设置成非阻塞模式。
说明2:上层应用程序app2轮询调用recv函数,接受数据。若缓冲区没有数据,上层程序app2不会阻塞,recv返回值为-1,错误码是EWOULDBLOCK。
说明3:上层应用程序不断轮询有没有数据到来。会造成上层应用忙等待。大量消耗CPU。很少直接用。应用范围小,一般和selectIO复用配合使用。
I/O复用
说明1:上层应用程序app3调用select机制(该机制有linux内核支持,避免了app3忙等待。),进行轮询文件描述符的状态变化。
说明2:当select管理的文件描述符没有数据(或者状态没有变化时),上层应用程序app3也会阻塞。
说明3:好处select机制可以管理多个文件描述符
说明4:select可以看成一个管理者,用select来管理多个IO。
一旦检测到的一个I/O或者多个IO,有我们感兴事件,发生,select函数将返回,返回值为检测到的事件个数。进而可以利用select相关api函数,操作具体事件。
说明5:select函数可以设置等待时间,避免了上层应用程序app3,长期僵死。
说明6: 和阻塞IO模型相比,selectI/O复用模型相当于提前阻塞了。等到有数据到来时,再调用recv就不会发生阻塞。
信号驱动I/O
说明1:上层应用程序app4建立SIGIO信号处理程序。当缓冲区有数据到来,内核会发送信号告诉上层应用程序app4。
说明2:上层应用程序app4接收到信号后,调用recv函数,因缓冲区有数据,recv函数一般不会阻塞。
说明3:这种用于模型用的比较少,属于典型的“拉模式”。即:上层应用app4,需要调用recv函数把数据拉进来。
异步I/O
说明1:上层应用程序app5调用aio_read函数,同时提交一个应用层的缓冲区buf;调用完毕后,不会阻塞。上层应用程序app5可以继续其他任务。
说明2:当tcpip协议缓冲区有数据时,linux主动的把内核数据copy到用户空间。然后再给上层应用app5发送信号;告诉app5数据有了,赶快处理吧!
说明3:典型的“推模式”
说明4:效率最高的一种形式,上层应用程序app5有异步处理的能力(在linux内核的支持下,言外之意:处理其他任务的同时,也可支持IO通讯)。异步I/O指的是什么?
上层应用程序app5,在也可以干别的活的时,可以接收数据(接受异步通信事件。===)异步命令来源)。与信号驱动IO模型,上层应用程序app5不需要调用recv函数。
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
如果成功,返回所有sets中描述符的个数;如果超时,返回0;如果出错,返回-1。
- 监视readfds来查看是否read的时候会被堵塞,注意,即便到了end-of-file,fd也是可读的。
- 监视writefds看写的时候会不会被堵塞。
- 监视exceptfd是否出现了异常。主要用来读取OOB数据,异常并不是指出错。
- 注意当一个套接口出错时,它会变得既可读又可写。
- 如果有了状态改变,会将其他fd清零,只有那些发生改变了的fd保持置位,以用来指示set中的哪一个改变了状态。
- 参数n是所有set里所有fd里,具有最大值的那个fd的值加1
fd_set
四个宏用来对fd_set进行操作:
FD_CLR(int fd, fd_set *set); //不监视相关位
FD_ISSET(int fd, fd_set *set); //在select调用之后,检测fd位是否为1
FD_SET(int fd, fd_set *set); //设置fd位成为要监视的目标
FD_ZERO(fd_set *set); //不监视任何位且所有位为0
这一套宏,没有一个功能是 将相关位置成0
- FD_ZERO用来清空set;
- FD_SET和FD_CLR用来对某个set添加和删除一个fd;
- FD_ISSET用来指示一个fd是不是一个set的一部分。他很有用,用来看select后哪一个fd可用了。
FD_ZERO(&rfds); //不监视任何位且所有位为0
FD_SET(stdinin, &rfds); //设置stdinin位成为要监视的目标
FD_SET(sockfd, &rfds); //设置sockfd位成为要监视的目标int ret = select(maxfd + 1, &rfds, NULL, NULL, NULL); //如果rfds是可操作状态,也就是非阻塞了,就返回.并且相关位置1
time_out
timeout是从调用开始到select返回前,会经历的最大等待时间。
两种特殊情况:如果为值为0,会立刻返回。
如果timeout是NULL,会阻塞式等待。
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
一些调用使用3个空的set, n为zero, 一个非空的timeout来达到较为精确的sleep.
Linux中, select函数改变了timeout值,用来指示还剩下的时间,但很多实现并不改timeout。
为了较好的可移植性,timeout在循环中需要被重新赋初值。
- timeout== NULL
– 无限等待
– 被信号打断时返回1, errno 设置成EINTR
- timeout->tv_sec == 0 && tvptr->tv_usec == 0
– 不等待立即返回
- timeout->tv_sec != 0 || tvptr->tv_usec != 0
– 等待特定时间长度, 超时返回0
linux第7天 I/O的五种模型, select的更多相关文章
- 图解I/O的五种模型
1.1 五种I/O模型 1)阻塞I/O 2)非阻塞I/O 3)I/O复用 4)事件(信号)驱动I/O 5)异步I/O 1.2 为什么要发起系统调用? 因为进程想要获取磁盘中的数据,而能和磁盘打交道的只 ...
- IO的五种模型
为了区分IO的五种模型,下面先来看看同步与异步.阻塞与非阻塞的概念差别. 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.按照这个定义,其实绝大多数函数都是同步调用(例如 ...
- 2. 彤哥说netty系列之IO的五种模型
你好,我是彤哥,本篇是netty系列的第二篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 本文将介绍linux中的五种IO模型,同时也会介绍阻塞/非阻塞与同步/异步的区别. ...
- IO 的五种模型是什么
目录 前言 用户空间和内核空间 IO 五种模型 阻塞型 IO 非阻塞 IO IO 多路复用 信号驱动 IO 异步 IO 总结 阻塞和非阻塞 同步与异步 前言 我们经常看到阻塞/非阻塞,同步/异步这两组 ...
- 【网络IO系列】IO的五种模型,BIO、NIO、AIO、IO多路复用、 信号驱动IO
前言 在上一篇文章中,我们了解了操作系统中内核程序和用户程序之间的区别和联系,还提到了内核空间和用户空间,当我们需要读取一条数据的时候,首先需要发请求告诉内核,我需要什么数据,等内核准备好数据之后 , ...
- Linux-I/O五种模型
一. 概念说明 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 I/O 同步(Sync)/异步(Async) 阻塞(Block)/非阻塞(Unbloc ...
- socket编程五种模型
客户端:创建套接字,连接服务器,然后不停的发送和接收数据. 比较容易想到的一种服务器模型就是采用一个主线程,负责监听客户端的连接请求,当接收到某个客户端的连接请求后,创建一个专门用于和该客户端通信的套 ...
- Linux IO的五种模型 ongoing
服务器端编程经常需要构造高性能的IO模型,常见的IO模型: 阻塞I/O模型 (Blocking IO) ------------(同步)(阻塞) 非阻塞I/O模型 (Non-Blocking IO) ...
- []转帖] 浅谈Linux下的五种I/O模型
浅谈Linux下的五种I/O模型 https://www.cnblogs.com/chy2055/p/5220793.html 一.关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是 ...
随机推荐
- xcode 路径
$(SRCROOT)宏和$(PROJECT_DIR)宏 XCode环境变量及路径设置 分类: Objective-C2013-03-11 12:30 41336人阅读 评论(1) 收藏 举报 一般我们 ...
- QObject::deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,下一次主消息循环收到这个event之后才会销毁对象 good
程序编译运行过程很顺利,测试的时候也没发现什么问题.但后来我随手上传了一个1G大小的文件,发现每次文件上传到70%左右的时候程序就崩溃了,小文件就没这个问题.急忙打开任务管理器,这才发现上传文件的时候 ...
- MyBatis3资料网址
官网: http://mybatis.github.io/mybatis-3/zh/index.html 资料: http://www.open-open.com/doc/list/112?o=d 整 ...
- Linux 下动态库 / 静态库(依赖)
一. 依赖动态库的动态库 libfun.so依赖动态库libtest.so(libfun.so动态库里的函数intnothing()调用了libtest.so里的intmytest()函数),而mai ...
- Jquery调用webService的四种方法
1.编写4种WebService方法 [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(Conf ...
- 登录不到phpmyadmin
或许出现以下错误情况:phpmyadmin:#1045 无法登录 MySQL 服务器.Access denied for user ‘root’@’localhost’ (using password ...
- LeetCode Combination Sum III
原题链接在这里:https://leetcode.com/problems/combination-sum-iii/ 题目: Find all possible combinations of k n ...
- cp 命令(转)
cp命令用来复制文件或者目录,是Linux系统中最常用的命令之一.一般情况下,shell会设置一个别名,在命令行下复制文件时,如果目标文件已经存在,就会询问是否覆盖,不管你是否使用-i参数.但是如果是 ...
- App开发需要了解的基本技术
本文针对小白用户对App做一个简单的介绍,首先要了解App都有哪些类型,不同的类型适用于哪些需求,用户可以根据自己的需求选择不同的App开发. 一 App有哪些形式 WebApp:简单来说,Web A ...
- SoapUI接口测试·第一个HTTP Request接口请求和断言
一.新建SOAP项目 [File]-[New SOAP Project],在[Project Name]输入{工程名},点击[OK]. 二.新建TestSuite 选中项目,右键选择[New Te ...