关于操作系统相关问题
linux进程间的通信方式
1、管道(pipe)、流管道(s_pipe)、有名管道(FIFO)。
2、信号(signal) 。
3、消息队列。
4、共享内存。
5、信号量。
6、套接字(socket) 。
linux的硬链接和软连接
inode储存文件的元组信息, Linux 下的文件是通过索引节点(inode)来识别文件,硬链接可以认为是一个指针,指向文件索引节点的指针,系统并不为它重新分配 inode 。每添加一个一个硬链接,文件的链接数就加 1
软链接克服了硬链接的不足,没有任何文件系统的限制,任何用户可以创建指向目录的符号链接
linux调优相关
cpu相关:程序调整优先级,不重要的优先级相对低一些,更新cpu
内存相关: free内存,swap分区,buffcache,调整page大小,降低page-out速度
网络相关:内核中调整网络参数
通过调整net.ipv4.tcp_tw_reuse参数让处于TIME_WAIT状态的Socket对新连接可重用
通过调整tcp_fin_timeout参数,让处于FIN-WAIT-2状态的Socket可以早一些关闭,进而节省内存
通过调整tcp_keepalive_time参数,调整keepalive连接的关闭时间
通过调整tcp_max_syn_backlog参数来调整最大能够容纳的处于半连接状态的socket的数量
关闭一些不需要的服务以及端口号
linux常用命令
cd, pwd, ls, ll(更详细) -a,touch创建文件,mkdir 创建目录, cat 查看日志文件, more分页查看, less可定位到最后一页
tail -f, cp复制,mv移动, rm 删除,grep 字符串模糊搜索, find查找文件, | 管道命令, tar解压缩, ps -ef -aux查看系统进程
netstat 显示网络状态, ping 测试连通, top查看正在执行的进程, free查看内存相关, sar -n DEV 显示网口统计数据(吞吐率,PPS)
sar -n TCP 显示tcp统计数据 netstat -nlp socket信息 ss -ltnp socket信息 ss -s连接数 netstat -s 查连接数
ping 查看连通性和延时 kill -1 查看所有信号 kill -9 杀死进程
linux调整优先级
ps -ef, top查看进程信息,PR值和NI值
NI是优先级,用户态的概念,PR是内核态的优先级,一般情况下,PR=NI+20, 如果一个进程的优先级PR是20, 那么它的NI(nice)值就是20-20=0
可以通过改变NI来改变PR
NI的调整范围是-20到19
renice [number] PID
renice -n (nice值) -p (process进程值) :改单一进程优先级;
renice -n (nice值) -g (group组名):改整个组员的优先级;
renice -n (nice值) -u (user用户名):改用户的优先级;
linux 内核态,用户态
内核态:控制计算机的硬件资源,例如协调CPU资源,分配内存资源,并且提供稳定的环境供应用程序运行
用户态:提供应用程序运行的空间,为了使应用程序访问到内核管理的资源例如CPU,内存,I/O。内核必须提供一组通用的访问接口,这些接口就叫系统调用
进程
进程是系统进行资源分配和调度的一个独立单位,程序段、数据段、PCB三部分组成了进程实体,PCB是唯一标识符(进程标识符,进程控制信息,状态)
进程五个状态
创建态: 操作系统为进程分配资源,初始化PCB
就绪态:运行资源等条件都满足,存储在就绪队列中,等待CPU调度
运行态:CPU正在执行进程
阻塞态:等待某些条件满足,等待消息回复,等待同步锁,sleep等,阻塞队列
终止态 :回收进程拥有的资源,撤销PCB
进程的调度
非剥夺调度方式(非抢占方式),只允许进程主动放弃,主动要求进入阻塞才会终止
剥夺调度方式(又称抢占方式)当一个进程正在处理机上执行时,如果有一个优先级更高的进程需要处理机,则立即开中断暂停正在执行的进程,将处理机饭呢陪给优先级高的那个进程
进程切换
1、对原来的进程数据保存
2、对新的进程数据恢复
调度算法
时间片轮询
按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片(如100ms)。若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放到就绪队列队尾重新排队
适用于分时操作系统,由于高频率的进程切换,因此有一定开销;不区分任务的紧急程度
优先级调度
每个作业/进程有各自的优先级,调度时选择优先级最高的作业/进程
适用于实时操作系统,用优先级区分紧急程度,可灵活地调整对各种作业/及进程的偏好程度
多级反馈队列调度
设置多级优先队列各级别队列优先级从高到底,时间片从小到大
进程死锁
多个进程因循环等待而造成的无法执行的现象
互斥使用,不可抢占,请求保持,循环等待
线程
线程的是实现方式:
用户级线程:用户级线程由应用程序通过线程库是实现如python (import thread), 线程的管理工作由应用程序负责。
内核级线程:内核级线程的管理工作由操作系统内核完成,线程调度,切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成
线程锁
独占锁-共享锁:当一个共享资源只有一份的时候,通常我们使用独占锁
互斥锁-自旋锁:
如果一个线程已经锁定了一个互斥锁,第二个线程又试图去获取这个互斥锁,则第二个线程将会被挂起(即休眠、不占用 CPU 资源)
指当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环
当资源等待的时间较长,用互斥锁让线程休眠,会消耗更少的资源,当资源等待的时间较短时,使用自旋锁将减少线程的切换,获得更高的性能
重入锁:也叫作递归锁,指的是同一线程内,外层函数获得锁之后,内层递归函数仍然可以获取到该锁
读写锁:读写锁允许同一时刻被多个读线程访问,但是在写线程访问时,所有读线程和其他的写线程都会被阻塞。简单可以总结为,读读不互斥,读写互斥,写写互斥,可针对场景升级降级锁
进程与线程的区别
进程和线程的关系:一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。CPU的最小调度单元是线程,所以单进程多线程是可以利用多核CPU的
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别
协程
Coroutines 是一种比线程更加轻量级的微线程。类比一个进程可以拥有多个线程,一个线程也可以拥有多个协程
协程通过在线程中实现调度,避免了陷入内核级别的上下文切换造成的性能损失,进而突破了线程在IO上的性能瓶颈。
完全由用户实现控制,有自己的上下文及寄存器和栈
python的协程源于yield指令
yield item 用于产出一个值,反馈给next()的调用方法
让出处理机,暂停执行生成器,让调用方继续工作,直到需要使用另一个值时再调用next()
协程式对线程的调度,yield类似惰性求职方式可以视为一种流程控制工具,实现协作式多任务,python3.5引入了async/await表达式,使得协程证实在语言层面得到支持和优化,大大简化之前的yield写法。线程正式在语言层面得到支持和优化。线程是内核进行抢占式调度的,这样就确保每个线程都有执行的机会。而coroutine运行在同一个线程中,有语言层面运行时中的EventLoop(事件循环)来进行调度。在python中协程的调度是非抢占式的,也就是说一个协程必须主动让出执行机会,其他协程才有机会运行。让出执行的关键字 await, 如果一个协程阻塞了,持续不让出CPU处理机,那么整个线程就卡住了,没有任何并发。
goalng协程模型
cpu的使用率与负载
local average,平均负载,1分钟,5分钟,15分钟
负载高利用率低:说明io密集型任务,,任务较多,查看是否有p+状态的进程,睡眠不可终止的进程,重启,恢复依赖资源
负载低利用率高:说明任务执行时间长,根据任务看代码, top操作