操作系统
1. 进程与线程的本质区别、以及各自的使用场景
答:进程是操作系统分配资源的基本单位,线程是cpu调度的基本单位。
线程非共享的,errno变量,独立的栈空间,未决信号集,寄存器和栈指针(指向内核栈)
线程的优点:
通信方便(socket,fifo,pipe,mmap,消息队列),共享数据方便
开销小,提高了程序的并发性
线程的缺点:
库函数调用,并不稳定,对信号不友好(信号的处理方式是共享的),调试困难,不支持gdb
各自的使用场景:
线程:在等待I/O的时候,可以交给一个线程去做,继续去做别的事情
进程:需要安全稳定的时候使用线程,虽然创建一个进程的花费比线程一个大
2. 线程可以看做寄存器和栈的集合,这句话怎么理解?
答:
首先,从内核的角度来看,线程和进程是类似的,都拥有独立的pcb。但是每个线程都有各自的任务需要去执行,这些都保存在各自的寄存器和栈中。在线程中调用函数的时候,是通过栈帧结构实现的。调用函数的时候,将 函数参数,返回地址,ebp指针,esp指针压入栈中进行保存。然后移动ebp指针和esp指针重新为函数创建一个栈帧结构。
因为ebp指针和sep指针的值是储存在寄存器中,并且函数运行空间的申请,参数,函数地址的保存等需要通过栈来实现,所以,线程可以看做寄存器和栈的集合
3. 线程号和线程ID的区别?
线程号是cpu分配时间轮片的依据,而线程ID是用来区分线程的。
两个不同的进程中,线程ID可以相同,但是线程号绝对不能相同
4. 进程状态?
就绪态(等待cpu分配时间轮片),挂起态(主动放弃cpu,等待除cpu以外的其他资源),执行态(占用cpu),终止态
5. 进程调度算法的特点以及使用场景?
1>先来先去服务(FCFS),总是把在任务队列之首的进程调整到运行状态,完成一个进程再去做下一个进程
使用场景,有利于长作业和CPU繁忙的作业
缺点是,不利于短作业和I/O频繁的作业
2> 短作业优先调度算法(SJF),对预计运行时间少的进程先去处理,通常后面来的进程不会去抢夺正在运行的进程的资源
使用场景:短作业比较多的场景,能提高系统的吞吐量,比fcfs算法节省时间
缺点,对长作业不利,可能长时间得不到执行,无法根据紧迫程度来划分执行优先级
3>轮转法
让每个进程在就绪队列中等待的时间和享受的服务的时间成正比
适用场景:用户通常在一个时间片内处理完,否则会使响应时间,平均周转时间延长
4>多级反馈队列算法
是轮转法和优先级算法的综合和发展
设置多个就绪队列,分别赋予不同的优先级,如逐级降低,队列1的优先级最高,如果要加入一个新的线程,先加在队列1的底部,
如果按照队列1一个时间片未能执行完,则降低投入到队列2的末尾,依次类推,直到进程完成
6. 协程的作用
协程是单进程单线程的超越函数的调度机制,通过一定的调度手段进行调度
7. 进程通信方法的特点以及适用场景?
pipe匿名管道,只能用于有血缘关系的进程之间
fifo有名管道,可以用户非血缘关系的进程之间
mmap共享内存,都可以使用,通过虚拟内存来实现对物理内存的一个控制
信号,一般用于通信,数据传输能力较差
socket套接字通信,一般用于网络通信,可以用于进程通信(socket可以看做用户进程和内核网络协议的编程接口)
8. 死锁必要条件,解决死锁的策略?
死锁的产生条件,第一个,上锁两次。第二个,A拥有t1锁的权限,但是想要获得t2锁的权限;B拥有t2锁的权限,但是想要获得t1锁的权限。
解决策略:
1). 编码规范
2). 在想要获取其他锁的时候,先放开自己所拥有的的锁
9. 虚拟内存的作用,mmu作用?
虚拟内存定义:是计算机系统系统管理的一种技术,使得应用程序认为它拥有连续的可用的内存。
实际上是被分割成多个物理内存,还有部分暂时存储在外部的磁盘存储器上
为什么要有虚拟内存呢?
如果是多个线程的话,非常容易发生某个进程不小心占用了另一个进程所使用的内存,导致程序运行出错
虚拟内存作用:缓存,内存管理,内存保护
1> 有利于进程之间的隔离
2>为每个进程提供了一致的地址空间,简化内存管理
3> 将主存储器看做一个存储在磁盘上的地址空间的高速缓存,在主存储器中只保存活动区域,并根据需要在磁盘和主存储器之间来回传送数据
mmu作用:实现连续的虚拟地址访问不连续的物理地址;方便进程之间的隔离;设置内存访问级别
10. 比较分页存储管理和分段存储管理的区别
1> 页是信息的物理单位,由系统硬件确定;而端是一个逻辑单位,含有一组意义相对完整的信息
2>分页的作业地址空间是一维的,也就是单一的线性地址空间;分段的作业地址是二维的,在标识一个地址的时候,既需要给出段名,还需要给出段内地址
11. 分析静态链接,动态链接的优缺点(分析静态库和动态库的优缺点)
静态库优点:
1> 加载速度快
2> 不需要打包库
静态库缺点:
1>程序发生改变需要重新编译
2>可执行文件体积大
动态库优点:
1> 在函数接口不变的前提下,不需要重新编译
2>体积小
动态库缺点:
1>加载速度慢
2>需要打包库
linux
1. inode机制
为什么要有inode节点机制?
1> 如果文件名包含特殊字符,无法直接删除,可以通过直接删除inode节点就能实现对这个文件实现删除操作
2> 对文件进行移动或者重命名,不会影响inode节点
3.>更新的时候,生成一个新的inode节点,然后在这个节点保存新的版本,然后当文件重新打开的时候,文件会自动指向这个新的inode节点
对inode机制的解释
每一个进程会分配一个4G的虚拟内存,在3G~4G内核空间中,存在PCB进程控制块,在PCB进程控制块中,存在文件描述符表,文件描述符就是文件描述符表的下标,每一个表项指向一个file结构额如题
在file结构中记录着这个文件的打开次数,引用计数,还有指向file_operatiors结构体的指针,还有指向dentry(目录项)结构体的指针。
在file_operations结构体中封装了一些对文件进行操作的函数
在dentry结构体中还有一个指向inode结构体的指针,这个结构体保存了文件的所有者,块的大小,文件的属性,块的位置等等
2. 硬链接和软连接的区别?
硬链接是file结构体对应的文件的引用计数增加1,只有当引用计数为0的时候这个文件才会被释放,也就是说如果源文件你删除了,但是在这之前你对这个文件创建了硬链接,那么这个文件的file结构体中的引用计数
不为0,这个文件就不会删除
软连接相当于创建了一个快捷方式,并不会增加引用计数,当源文件删除的时候,这个软连接就失效了
3. 常用的命令?
lscpu 描述cpu相关的信息
pwd 资源管理器
grep 文本搜索命令
awk 文件搜索命令
4. 僵尸进程和孤儿进程的区别?
孤儿进程:
父进程先于子进程死去,这个子进程将由init进程进行托管
僵尸进程:
父进程在死去的时候,没有调用wait函数或者对waitpid函数对子进程进行回收,这样的话,就会造成一个资源的浪费。子进程的进程描述符也会一直被占用
如何防止僵尸进程:
1> 将僵尸进程变成孤儿进程(两次fork),这样init进程就会对僵尸进程实现一个自动回收
2>调用wait/waitpid函数对子进程进行回收
3>信号驱动,当子进程发出SIGCHLD信号的时候,父进程调用wait/waitpid函数(默认的处理动作是忽略,需要对信号处理方式进行自定义),避免子进程变成僵尸进程