Linux
下/proc
Linux
系统上的/proc
目录是一种文件系统,即proc
文件系统。与其它常见的文件系统不同的是,/proc
是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。基于上述特殊性,其内的文件也常被称作虚拟文件,并具有一些独特的特点。例如,其中有些文件虽然使用查看命令查看时会返回大量信息,但文件本身的大小却会显示为0字节。此外,这些特殊文件中大多数文件的时间及日期属性通常为当前系统时间和日期,这跟它们随时会被刷新(存储于RAM中)有关。
为了查看及使用上的方便,这些文件通常会按照相关性进行分类存储于不同的目录甚至子目录中。
/proc/scsi
- 当前系统上所有SCSI设备的相关信息
/proc/N
- 系统当前正在运行的进程的相关信息(也就是说,在某进程结束后其相关目录则会消失)
目录
/proc/buddyinfo
- 用于诊断内存碎片问题的相关信息文件
/proc/cmdline
- 在启动时传递至内核的相关参数信息,这些信息通常由lilo或grub等启动管理工具进行传递
/proc/cpuinfo
- 处理器的相关信息的文件
/proc/crypto
- 系统上已安装的内核使用的密码算法及每个算法的详细信息列表
/proc/devices
- 系统已经加载的所有块设备和字符设备的信息,包含主设备号和设备组(与主设备号对应的设备类型)名
/proc/diskstats
- 每块磁盘设备的磁盘I/O统计信息列表
/proc/dma
- 每个正在使用且注册的
ISA DMA
通道的信息列表
- 每个正在使用且注册的
/proc/execdomains
- 内核当前支持的执行域(每种操作系统独特“个性”)信息列表
/proc/fb
- 帧缓冲设备列表文件,包含帧缓冲设备的设备号和相关驱动信息
/proc/filesystems
- 当前被内核支持的文件系统类型列表文件,被标示为
nodev
的文件系统表示不需要块设备的支持;通常mount
一个设备时,如果没有指定文件系统类型将通过此文件来决定其所需文件系统的类型
- 当前被内核支持的文件系统类型列表文件,被标示为
/proc/interrupts
X86
或X86_64
体系架构系统上每个IRQ
相关的中断号列表;多路处理器平台上每个CPU
对于每个I/O
设备均有自己的中断号
/proc/iomem
- 每个物理设备上的记忆体(
RAM
或者ROM
)在系统内存中的映射信息
- 每个物理设备上的记忆体(
/proc/ioports
- 当前正在使用且已经注册过的与物理设备进行通讯的输入-输出端口范围信息列表
/proc/kallsyms
- 模块管理工具用来动态链接或绑定可装载模块的符号定义,由内核输出
/proc/kcore
- 系统使用的物理内存,以
ELF
核心文件(core file
)格式存储,其文件大小为已使用的物理内存(RAM
)加上4KB
;这个文件用来检查内核数据结构的当前状态,因此,通常由GBD
通常调试工具使用,但不能使用文件查看命令打开此文件
- 系统使用的物理内存,以
/proc/kmsg
- 此文件用来保存由内核输出的信息,通常由
/sbin/klogd
或/bin/dmsg
等程序使用,不要试图使用查看命令打开此文件
- 此文件用来保存由内核输出的信息,通常由
/proc/loadavg
- 保存关于
CPU
和磁盘I/O
的负载平均值,其前三列分别表示每1秒钟、每5秒钟及每15秒的负载平均值,第四列是由斜线隔开的两个数值,前者表示当前正由内核调度的实体(进程和线程)的数目,后者表示系统当前存活的内核调度实体的数目;第五列表示此文件被查看前最近一个由内核创建的进程的PID
- 保存关于
/proc/locks
- 保存当前由内核锁定的文件的相关信息,包含内核内部的调试数据
/proc/mdstat
- 保存RAID相关的多块磁盘的当前状态信息
/proc/meminfo
- 系统中关于当前内存的利用状况等的信息,常由
free
命令使用,也可使用文件查看命令直接读取此文件
- 系统中关于当前内存的利用状况等的信息,常由
/proc/mounts
- 在内核
2.4.29
版本以前,此文件的内容为系统当前挂载的所有文件系统 - 在
2.4.19
以后的内核中引进了每个进程使用独立挂载名称空间的方式,此文件则随之变成了指向/proc/self/mounts
(每个进程自身挂载名称空间中的所有挂载点列表)文件的符号链接
- 在内核
/proc/modules
- 当前装入内核的所有模块名称列表,可以由
lsmod
命令使用,也可以直接查看
- 当前装入内核的所有模块名称列表,可以由
/proc/partitions
- 块设备每个分区的主设备号(
major
)和次设备号(minor
)等信息,同时包括每个分区所包含的块(block
)数目
- 块设备每个分区的主设备号(
/proc/pci
- 内核初始化时发现的所有
PCI
设备及其配置信息列表,其配置信息多为某PCI
设备相关IRQ
信息
- 内核初始化时发现的所有
/proc/slabinfo
- 在内核中频繁使用的对象(如
inode
、dentry
等)都有自己的cache
,即slab pool
,而/proc/slabinfo
文件列出了这些对象相关slap
的信息
- 在内核中频繁使用的对象(如
/proc/stat
- 实时追踪自系统上次启动以来的多种统计信息
/proc/swaps
- 当前系统上的交换分区及其空间利用信息,如果有多个交换分区的话,则会每个交换分区的信息分别存储于
/proc/swap
目录中的单独文件中,而其优先级数字越低,被使用到的可能性越大
- 当前系统上的交换分区及其空间利用信息,如果有多个交换分区的话,则会每个交换分区的信息分别存储于
/proc/uptime
- 系统上次启动以来的运行时间
/proc/version
- 当前系统运行的内核版本号
/proc/vmstat
- 当前系统虚拟内存的多种统计数据
/proc/zoneinfo
- 内存区域(
zone
)的详细信息列表
- 内存区域(
~/.profile
和/etc/profile
当登入系统时候获得一个shell进程时,其读取环境设定档有三步 :
- 首先读入的是全局环境变量设定档
/etc/profile
,然后根据其内容读取额外的设定的文档,如/etc/profile.d
和/etc/inputrc
- 然后根据不同使用者帐号,去其家目录读取
~/.bash_profile
,如果这读取不了就读取~/.bash_login
,这个也读取不了才会读取~/.profile
,这三个文档设定基本上是一样的,读取有优先关系- 然后在根据用户帐号读取
~/.bashrc
/etc/profile
,/etc/bashrc
是系统全局环境变量设定~/.profile
,~/.bashrc
是用户家目录下的私有环境变量设定
~/.profile
可以设定本用户专有的路径,环境变量等,它只在登入的时候执行一次~/.bashrc
也是某用户专有设定文档,可以设定路径,命令别名,每次shell script
的执行都会使用它一次
Linux
下查看内存情况
free
显示系统内存的使用情况,包括物理内存、交换内存(swap)和内核缓冲区内存等
vmstat
对操作系统的虚拟内存、进程、CPU活动进行监控,是对系统的整体情况进行的统计
memory列
swpd
- 使用的虚拟内存大小
free
- 空闲物理内存大小
buff
buff cache
内存大小cache
page cache
内存大小
top
可以查看正在运行的进程和系统负载信息,包括
cpu
负载、内存使用、各个进程所占系统资源等
cat /proc/meminfo
/proc/meminfo
是了解Linux
系统内存使用状况的主要接口,我们最常用的free
、vmstat
等命令就是通过它获取数据的
ps aux
查看系统中各个进程的运行情况,包括了进程占用的内存,
%MEM
列就是各个进程的内存占用百分比
TCP拥塞控制
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这样的情况叫网络拥塞。
在计算机网络中,数位链路容量(带宽),交换结点中的缓存以及处理机等,都是网络的资源。
当出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。
当输入的负载到达一定程度,吞吐量不会增加,也就是一部分网络资源会丢失掉。
控制算法
- 满开始
- 拥塞控制
- 快重传
- 快恢复
TCP流量控制
双方在进行通信的时候,发送方的速率和接收方的速率是不一定相等的。
如果发送方的发送速率太快,会导致接收方处理不过来。这时候接收方只能把处理不过来的数据存放在缓存区里(其中,失效的数据也会被存放到缓存区里的)。这时,如果缓冲区满了,发送方还在不断地发送着数据,那接收方只能把收到的数据包丢掉,大量的数据包被丢掉这会极大的浪费网络资源的。
因此,需要控制发送方的发送速率,让接收方与发送方处于一种动态平衡会比较好。而对发送方的发送速率控制,即流量控制。
方法
接收方每次收到数据包,可以在发送确定报文的时候,同时告诉发送方自己的缓存区还剩余多少是空闲的,我们也把缓存区的剩余大小称之为接收窗口大小。
发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生。
再次发数据
当发送方停止发送数据后。
接收方处理好数据,接受窗口 win > 0 时,接收方发个通知报文去通知发送方,告诉他可以继续发送数据了。当发送方收到窗口大于0的报文时,就继续发送数据。不过这时候可能会遇到一个问题,假如接收方发送的通知报文,由于某种网络原因,这个报文丢失了,这时候就会引发一个问题:接收方发了通知报文后,继续等待发送方发送数据,而发送方则在等待接收方的通知报文,此时双方会陷入一种僵局。
为了解决这种问题,我们采用了另外一种策略:当发送方收到接受窗口 win = 0 时,这时发送方停止发送报文,并且同时开启一个定时器,每隔一段时间就发个测试报文去询问接收方,打听是否可以继续发送数据了,如果可以,接收方就告诉他此时接受窗口的大小;如果接受窗口大小还是为0,则发送方再次刷新启动定时器。
注意
- 由于
TCP/IP
支持全双工传输,因此通信的双方都拥有两个滑动窗口,一个用于接受数据,称之为接收窗口;一个用于发送数据,称之为拥塞窗口(即发送窗口)。指出接受窗口大小的通知我们称之为窗口通告。- 在现在的
TCP
协议中,接受窗口的大小是根据某种算法动态调整的。- 接受窗口如果太小的话,显然这是不行的,这会严重浪费链路利用率,增加丢包率。当接收窗口达到某个值的时候,再增大的话也不怎么会减少丢包率的了,而且还会更加消耗内存。所以接收窗口的大小必须根据网络环境以及发送发的的拥塞窗口来动态调整。
- 接收方在发送确认报文的时候,会告诉发送方自己的接收窗口大小,而发送方的发送窗口会据此来设置自己的发送窗口,但这并不意味着他们就会相等。首先接收方把确认报文发出去的那一刻,就已经在一边处理堆在自己缓存区的数据了,所以一般情况下接收窗口 >= 发送窗口。
为什么map是用红黑树实现的
红黑树是二叉查找树,但在每个节点增加一个存储为表示节点的颜色,可以是红色或黑色(非红即黑),通过对任意一条从根到叶子的路径上各个节点着色方式的限制,红黑树确保没有一条路径会比其他路径长两倍。
因此,它是一种弱平衡二叉树,相对于严格的AVL
树来说,它的旋转次数少,所以对于查找、插入、删除较多的情况下,通常使用红黑树。
比较
AVL
是严格平衡的,频繁的插入和删除,会引起频繁的rebalance
,导致效率降低;
红黑树是弱平衡的,算是一种折中,插入最多旋转2次,删除最多旋转3次。所以红黑树在查找、插入删除的复杂度都是
O(logn)
,且性能稳定,所以STL
里面很多结构包括map底层都是使用的红黑树。
TCP三次握手
客户端发送连接请求到服务端
- 客户端发送:
SYN
服务端收到消息后知道自己是可以与客户端连接成功的。
但是客户端并不知道服务端有没有收到它的请求,所有服务端收到消息之后得应答,告诉客户端它收到请求了。
ACK(SYN)
服务端同时也会发送一个连接请求到客户端。
SYN
- 服务端发送:
ACK(SYN)
SYN
客户端收到服务端的反馈后,才会确定自己是可以与服务端连接上的。
- 客户端发送:
ACK
TCP四次挥手
建立连接时,被动方服务器端结束
CLOSED
阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN
和ACK
报文,开始建立连接。释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回
ACK
确认收到报文,经过CLOSE-WAIT
阶段准备好释放连接之后,才能返回FIN
释放连接报文。
Linux虚拟内存
概念
- 每个进程有独立的虚拟地址空间,进程访问的虚拟地址空间并不是真正的物理地址
- 虚拟地址可通过每个进程上页表与物理地址进行映射,获得真正的物理地址
- 如果虚拟地址所对应的物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已经耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中
分布
Linux使用虚拟地址空间,大大增加了进程的寻址空间,由低地址到高地址分别是:
- 只读段:该部分空间只能读,不能写,包括代码段,rodata段(C常量字符和#define定义的常量)
- 数据段:保存全局变量、静态空间变量
- 堆:就是平时所说的动态内存,malloc/new大部分都源于此。其中堆顶的位置可以通过brk和sbrk进行动态调整
- 文件映射区域:如动态库,共享内存等映射物理空间的内存,一般是mmap函数所分配的虚拟地址空间
- 栈:用于维护函数调用的上下文空间,一般为8M,可以通过ulimit -s查看
- 内核虚拟空间:用户代码不可见的区域,由内核管理
32
位系统有4G
的地址空间,其中0X08048000~0Xbfffffff
是用户空间,0Xc0000000~0Xffffffff
是内核空间,包含内核代码和数据、与进程相关的数据结构(如页表,内核栈)等。另外%esp
执行栈顶,往低地址方向变化;brk/sbrk
函数控制堆顶往高地址方向变化。
64
位系统地址空间大小不是2^32
,也不是2^64
,而一般是2^48
。
因为并不需要2^64
这么大的寻址空间,过大空间会导致资源的浪费。其中,
0x0000000000000000-0x00007fffffffffff
表用户空间
0xffff800000000000-0xffffffffffffffff
表示内核空间,并提供256TB
(2^48
)的寻址空间。用户空间由低地址到高地址仍然是只读段,数据段,堆,文件映射区和栈。
进程间通信方式
- 管道
- 无名管道
- 有名管道
- 消息队列
- 信号量
- 信号
- 共享内存
- socket
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 2019_11_0511/07
- ♥ 2020_04_2804/28
- ♥ 2020_11_0902/16
- ♥ 2022_03_0103/01
- ♥ 2022_03_0203/09
- ♥ 2022_02_24_0203/01