linux第7天


服务器端避免僵尸进程的方法:

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);

FD_SET(int fd, fd_set *set);

FD_ZERO(fd_set *set);

  • FD_ZERO用来清空set;
  • FD_SET和FD_CLR用来对某个set添加和删除一个fd;
  • FD_ISSET用来指示一个fd是不是一个set的一部分。他很有用,用来看select后哪一个fd可用了。

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

时间: 2024-10-04 15:10:03

linux第7天的相关文章

排查Linux机器是否已经被入侵

随着开源产品的越来越盛行,作为一个Linux运维工程师,能够清晰地鉴别异常机器是否已经被入侵了显得至关重要,个人结合自己的工作经历,整理了几种常见的机器被黑情况供参考 背景信息:以下情况是在CentOS 6.9的系统中查看的,其它Linux发行版类似 1.入侵者可能会删除机器的日志信息,可以查看日志信息是否还存在或者是否被清空,相关命令示例: [[email protected] ~]# ll -h /var/log/* -rw-------. 1 root root 2.6K Jul 7 18

linux下Nginx配置文件(nginx.conf)配置设置详解(windows用phpstudy集成)

linux备份nginx.conf文件举例: cp /usr/local/nginx/nginx.conf /usr/local/nginx/nginx.conf-20171111(日期) 在进程列表里 面找master进程,它的编号就是主进程号. ps -ef | grep nginx 查看进程 cat /usr/local/nginx/nginx.pid 每次修改完nginx文件都要重新加载配置文件linux命令: /usr/local/nginx -t //验证配置文件是否合法 若ngin

Linux下WebSphereV8.5.5.0 安装详细过程

Linux下WebSphereV8.5.5.0 安装详细过程 自WAS8以后安装包不再区别OS,一份介质可以安装到多个平台.只针对Installation Manager 进行了操作系统的区分 ,Websphere产品介质必须通过专门的工具Install Managere安装.进入IBM的官网http://www.ibm.com/us/en/进行下载.在云盘http://yun.baidu.com/share/linkshareid=2515770728&uk=4252782771 中是Linu

Linux centos下让alias自定义永久生效(+常用的别名)

alias可以简化一些复杂的命令串,使一个单词或简化后的命令即可实现复杂(通常是带很多参数的长串)命令. 基本用法: alias 简化命令='实际的长串命令'    //实际长串命令通常为'原命令 -/选项参数' eg. alias ll='ls -a' 获取别名: alias        //即可查看当前设定的所有alias别名 取消别名: unalias 简化命令 eg. unalias ll            //取消ll的别名 永久生效: 直接使用alias命令定义的别名,重启后就

Linux下修改环境变量PATH

1.什么是环境变量(PATH) 在Linux中,在执行命令时,系统会按照PATH的设置,去每个PATH定义的路径下搜索执行文件,先搜索到的文件先执行. 我们知道查阅文件属性的指令ls 完整文件名为:/bin/ls(这是绝对路径), 那你会不会觉得很奇怪:"为什么我可以在任何地方执行/bin/ls这个指令呢? " 为什么我在任何目录下输入 ls 就一定可以显示出一些讯息而不会说找不到该 /bin/ls 指令呢? 这是因为环境变量 PATH 的帮助所致呀! 当我们在执行一个指令癿时候,举例

老男孩Linux运维第41期20170917开班第四周学习重点课堂记录

第1章 必知必会文件 配置文件位置 该文件作用 /etc/sysconfig/network-scripts/ifcfg-eth0 第一块网卡的配置文件 同setup中的network /etc/resolv.conf 客户端DNS配置文件,优先级低于网卡配置文件 /etc/hosts 主要作用是定义IP地址和主机名的映射关系(域名解析),是一个映射IP地址和主机名的规定 /etc/sysconfig/network 用于配置hostname和networking /etc/fstab 开机自动

Linux基础命令小结

注意:Linux严格区分大小写 老男孩方法论经验之谈: 有一种方法叫做没方法 有两种方法,左右为难 有三种方法才叫有方法 停止一个命令:CTR + C 1.创建目录 英文:make directorys 命令:mkdir 实例:三种方式 mkdir /data cd / mkdir data cd /;mkdir data mkdir x y z    表示同时创建多个目录 mkdir -p /data/x/y   表示同时创建多级目录(递归创建),切记不可用mkdir /data/x/y 2.

Linux red hat 安装ansible

今日对Linux 系统是Red Hat Enterprise Linux Server release 6.5 (Santiago)对ansible进行安装. 由于系统的源为yum源,所以使用yum install ansible 进行安装,但是报错.如图.(这个错误是yum源没有注册到red hat 系统). yum源不能安装,所以换了一个思路.使用pip安装.pip是依赖python安装的. 1.检查Python版本 Python -v 检查出来为Python 2.6.6 2.检查pip 版

初识运维3--在虚拟机中安装Linux发行版系统(CentOS)的方法

在讲Linux系统发行版本的安装过程之前,先大略说明一下虚拟化. 虚拟化:将底层硬件资源抽象为用户更容易读懂和使用的逻辑抽象层的技术. 最早由IBM提出,现使用率较高的虚拟化软件平台有三类:VMware workstation.VirtualBOX.HyperV.在这里使用VMware workstation作为例子讲解说明安装过程. 虚拟化网络: 桥接模式:让物理机和虚拟机利用物理网络接口完成通信.虚拟机可以访问互联网. 仅主机模式:让虚拟机和物理机利用被虚拟出来的VMnet1网络接口完成通信

查看Linux系统版本信息

一.查看Linux内核版本命令(两种方法): 1.cat /proc/version [[email protected]CentOS home]# cat /proc/versionLinux version 2.6.32-431.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013 2.uname -a [