笔记-操作系统部分

进程和线程分别的概念 区别 适用范围 分别的通讯方式
进程概念:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.(资源、独立)
线程概念:线程是进程的一个实体,是CPU调度和分配的基本单位.(运算)
区别:
1)线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源
2)进程至少含一个线程(每个进程都有一个主线程),进程能创建、撤销线程.线程能创建线程,但不能创建进程(也就是说线程是进程的一部分)
3)进程在执行过程中拥有独立的内存单元,多个进程的资源不共享.而某个进程下的所有线程共享该进程所拥有的所有资源
4)进程崩溃不会影响其他进程;线程挂了其所属的进程也会挂.进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径.线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些.但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程.
5)进程拥有独立的资源,而线程只是含有少量运行中必不可少的资源.所以建一个进程的开销比线程大.
使用范围:
a.需要频繁创建销毁的优先使用线程;因为对进程来说创建和销毁一个进程代价是很大的.
b.线程的切换速度快,所以在需要大量计算,切换频繁时用线程,还有耗时的操作使用线程可提高应用程序的响应.
c.多进程可以使用在多机分布式系统,需要扩展到其他机器上,使用多进程,多线程适用于多核处理机.
d.需要更稳定安全时,适合选择进程;需要速度时,选择线程更好.
进程通信:
1.管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系通常是指父子进程关系.
2.有名管道(namedpipe):有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信.
3.信号量(semophore):信号量是一个计数器,可以用来控制多个进程对共享资源的访问.它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源.因此,主要作为进程间以及同一进程内不同线程之间的同步手段.
4.消息队列(messagequeue):消息队列是由消息的链表,存放在内核中并由消息队列标识符标识.消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点.
5.信号(sinal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生.
6.共享内存(shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问.共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的.它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信.
7.套接字(socket):套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信.
线程通信:
1.锁机制:包括互斥锁、条件变量、读写锁
①互斥锁提供了以排他方式防止数据结构被并发修改的方法.
②读写锁允许多个线程同时读共享数据,而对写操作是互斥的.
③条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止.对条件的测试是在互斥锁的保护下进行的.条件变量始终与互斥锁一起使用.
2.信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
3.信号机制(Signal):类似进程间的信号处理
线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制.

僵尸进程
阐述:启动一个程序,开始任务,然后等任务结束了,就停止这个进程.进程停止后,该进程就会从进程表中移除.但是,有时候有些程序即使执行完了也依然留在进程表中.那么,这些完成了生命周期但却依然留在进程表中的进程,称之为”僵尸进程”.
产生:当运行一个程序时,它会产生一个父进程以及很多子进程.所有这些子进程都会消耗内核分配给它们的内存和CPU资源.这些子进程完成执行后会发送一个Exit信号然后死掉.这个Exit信号需要被父进程所读取.父进程需要随后调用wait命令来读取子进程的退出状态,并将子进程从进程表中移除.若父进程正确第读取了子进程的Exit信号,则子进程会从进程表中删掉.但若父进程未能读取到子进程的Exit信号,则这个子进程虽然完成执行处于死亡的状态,但也不会从进程表中删掉.
是否对系统有害:不会.由于僵尸进程并不做任何事情,不会使用任何资源也不会影响其它进程,因此存在僵尸进程也没什么坏处.不过由于进程表中的退出状态以及其它一些进程信息也是存储在内存中的,因此存在太多僵尸进程有时也会是一些问题.
找出僵尸进程命令:ps aux grep Z
杀掉僵尸进程:kill -s SIGCHLD pid(将这里的pid替换成父进程的进程id,这样父进程就会删除所有以及完成并死掉的子进程了)

死锁是怎么产生及四个必要条件
产生死锁原因:1.因为系统资源不足;2.进程运行推进的顺序不合适;3.资源分配不当等
四个必要条件:
1.互斥条件:一个资源每次只能被一个进程使用
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

CPU的执行方式
1.取指令(IF,instruction fetch),即将一条指令从主存储器中取到指令寄存器的过程
2.指令译码阶段(ID,instruction decode),取出指令后,指令译码器按照预定的指令格式,对取回的指令进行拆分和解释,识别区分出不同的指令类别以及各种获取操作数的方法
3.执行指令阶段(EX,execute),具体实现指令的功能.CPU的不同部分被连接起来,以执行所需的操作
4.访存取数阶段(MEM,memory),根据指令需要访问主存、读取操作数,CPU得到操作数在主存中的地址,并从主存中读取该操作数用于运算
5.结果写回阶段(WB,write back),作为最后一个阶段,结果写回阶段把执行指令阶段的运行结果数据”写回”到某种存储形式

代码中遇到进程阻塞,进程僵死,内存泄漏等情况怎么排查
ps查询状态,分析dump文件

协程 协程和线程的区别
协程:当CPU在多个进程间切换时,那些后台程序就会处于这种暂停的状态,所以早年的电脑即使用一个CPU也可以同时处理多个进程任务.这是一种”伪多线程”的技术
区别:
1.协程属于线程,即一个线程下面可以开辟多个协程
2.协程是用户态的轻量级线程
3.协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈
4.当多个协程切换时,由于其同属于一个线程,所以可以看作是同步执行的,不存在同时共享资源的情况,可以不加锁的访问全局变量,切换上下文非常快
5.对于不需要cpu大量参与的业务场景来说,比如io广泛的业务,建议使用协程.

共享内存的使用实现原理
两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间
1.共享内存允许两个或更多进程共享一个给定的存储区,因为数据不需要再客户进程和服务进程之间复制.所以这是最快的一种ipc.
2.使用共享内存时需要注意:多个进程对共享内存的同步访问.
3.通常用信号量实现对共享内存的同步访问

ELF是什么?其大小与程序中全局变量的是否初始化有什么关系
Linux ELF ELF = Executable and Linkable Format,可执行连接格式

多线程和多进程的区别
1.数据共享、同步:多进程数据是分开的,共享复杂,需要用IP,同步简单;多线程共享进程数据,共享简单,同步复杂
2.内存、CPU:多进程占用内存多,切换复杂,CPU利用率低;多线程占用内存少,切换简单,CPU利用率高
3.创建销毁、切换:多进程创建销毁、切换复杂,速度慢;多线程创建销毁、切换简单,速度快
4.编程调试:多进程编程简单,调试简单;多线程编程复杂,调试复杂
5.可靠性:多进程进程间不会相互影响;多线程一个线程挂掉将导致整个进程挂掉
6.分布式:多进程适应于多核、多机分布,如果一台机器不够,扩展到多台机器比较简单;多线程适应于多核分布

常见的信号,信号怎么处理?
常见信号:
信号量值:2 名称:SIGINT 说明:终止信号
信号量值:3 名称:SIGQUIT 说明:暂停信号,放入后台
信号量值:4 名称:SIGILL 说明:非法指令
信号量值:5 名称:SIGTRAP 说明:进程异常终止
信号量值:7 名称:SIGBUS 说明:(虚实关系建立)总线错误(从写的位置到物理内存,操作系统没有将磁盘的开始位置到物理内存之间建立联系mmap(把虚拟内存和磁盘文件的关系映射起来,如果磁盘大小大于0,就建立这种关系
信号量值:9 名称:SIGKILL 说明:杀死进程
信号量值:11 名称:SIGSEGV 说明:段错误
信号量值:13 名称:SIGPIPE 说明:管道破裂
信号量值:14 名称:SIGALRM 说明:闹钟
信号量值:15 名称:SIGTERM 说明:缺省终止某个进程,终止掉
信号量值:17 名称:SIGSTOP 说明:子进程死的时候会给父进程发送这个信号
信号量值:19 名称:SIGCONT 说明:进程暂停
信号量值:23 名称:SIGURG 说明:紧急数据
信号量值:29 名称:SIGINFO 说明:异步IO
常用处理方式:
1.默认:如果是系统默认的话,那就会终止这个进程
2.忽略:信号来了我们不处理,装作没看到;SIGKILL,SIGSTOP不能忽略
3.捕获并处理:当信号来了,执行我们自己写的代码(捕获信号这个动作是需要我们完成的);SIGKILL,SIGSTOP不能捕获

Linux内核提供了哪些同步机制
1.禁用中断(单处理器不可抢占系统):对于单处理器不可抢占系统来说,系统并发源主要是中断处理.因此在进行临界资源访问时,进行禁用/使能中断即可以达到消除异步并发源的目的Linux系统中提供了两个宏local_irq_enable与local_irq_disable来使能和禁用中断.在linux系统中,使用这两个宏来开关中断的方式进行保护时,要确保处于两者之间的代码执行时间不能太长,否则将影响到系统的性能.(不能及时响应外部中断)
2.自旋锁:在多处理器系统中提供对共享数据的保护
3.信号量机制:在进程无法获取到临界资源的情况下,立即释放处理器的使用权,并睡眠在所访问的临界资源上对应的等待队列上;在临界资源被释放时,再唤醒阻塞在该临界资源上的进程.另外,信号量机制不会禁用内核态抢占,所以持有信号量的进程一样可以被抢占,这意味着信号量机制不会给系统的响应能力,实时能力带来负面的影响
4.互斥锁mutex:Linux内核针对count=1的信号量重新定义了一个新的数据结构struct mutex,一般都称为互斥锁.内核根据使用场景的不同,把用于信号量的down和up操作在struct mutex上做了优化与扩展,专门用于这种新的数据类型
5.RCU:RCU中的读取和写入操作无须考虑两者之间的互斥问题.但是写入者之间的互斥要考虑
6.完成接口completion:

linux系统的异步机制
1.信号:这是一种进程间通信的异步机制
2.epoll:这是一种高效处理IO的异步通信机制

exit() _exit()的区别
exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是”清理I/O缓冲”.

实现守护进程
(1)在父进程中执行fork并exit推出;
(2)在子进程中调用setsid函数创建新的会话;
(3)在子进程中调用chdir函数,让根目录”/“成为子进程的工作目录;
(4)在子进程中调用umask函数,设置进程的umask为0;
(5)在子进程中关闭任何不需要的文件描述符

linux的内存管理机制
Linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存

linux的任务调度机制
任务的调度需要进过两个过程:上下文切换和选择算法
1.上下文切换:从一个进程的上下文切换到另一个进程的上下文,因为其发生频率很高,所以通常都是调度器效率高低的关键.
2.选择算法:Linux schedule()函数将遍历就绪队列中的所有进程,调用goodness()函数计算每一个进程的权值weight,从中选择权值最大的进程投入运行.Linux的调度器主要实现在schedule()函数中
Schedule函数工作流程:清理当前运行中的进程 -> 选择下一个要运行的进程(pick_next_task) -> 设置新进程的运行环境 -> 进程上下文切换

标准库函数和系统调用的区别
1.在所有的ANSI C编译器版本中,C库函数是相同的;各个操作系统的系统调用是不同的
2.函数库调用调用函数库中的一段程序(或函数);系统调用调用系统内核的服务
3.函数库调用与用户程序相联系;系统调用是操作系统的一个入口点
4.函数库调用在用户地址空间执行;系统调用在内核地址空间执行
5.函数库调用的运行时间属于”用户时间”;系统调用的运行时间属于”系统”时间
6.函数库调用属于过程调用,调用开销较小;系统调用需要在用户空间和内核上下文环境间切换,开销较大
7.在C函数库libc中有大约300个函数;在UNIX中大约有90个系统调用
8.典型的C函数库调用:system fprintf malloc;典型的系统调用:chdir fork write brk

系统如何将一个信号通知到进程
1)A进程调用信号发送函数,发送信号给B,这是软中断,所以A进程会进入内核态运行操作系统的信号调度代码
2)操作系统发现B进程正在运行,于是写入管理B进程的某个数据结构
3)操作系统返回给A,A继续执行
4)B进程分配的处理器时间用完了,被时钟硬件中断
5)操作系统的时钟硬件中断处理函数准备挂起B进程,也就是把寄存器和函数堆栈保存起来,发现B进程收到了singal
6)操作系统在保存好B进程的stack和register后,新开stack(为了不干扰B进程真正的代码stack),激活B进程,B进程的信号处理函数

linux的常用命令
进程状态ps
查看cpu状态top
查看占用端口的进程号netstat grep

Linux的cpu 100排查
top,日志,gui工具

Linux系统结构
内核:操作系统的基本组件.没有它,操作系统将无法工作.内核管理着系统的资源,并与硬件进行通信.它负责内存、进程和文件的管理.
系统用户空间:系统级任务(如配置和软件安装)的管理层.它包括shell(命令行)、守护进程(在后台运行的进程)和桌面环境(用户交互界面).
应用:一种用于执行任务的软件.应用的范围涵盖了从桌面工具和编程语言到多用户业务套件等各种软件.大多数Linux发行版都会提供一个中央数据库,用于搜索和下载其他应用.

查看CPU负载
top,vmstat,sar,mpstat,iostat

linux设置core文件
1.ulimit -c:查看core文件的生成开关(结果为0,则表示关闭了此功能,不会生成core文件)
2.ulimit -c filesize:限制core文件的大小

linux设置开机自启动
1.编辑rc.loacl:vim /etc/rc.local
2.通过chkconfig添加自定义的启动脚本
3.自定义service服务