<Interview> 4.操作系统

1、进程间通信的方式有哪些?各自的优缺点及应用选择?
管道:只能单向传递,且只能在有亲缘关系的进程中使用
有名管道:也是单向传递,但可以在非亲缘进程中使用
信号量:可以用来控制多个进程对共享资源的访问
消息队列:消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺 点;
信号:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
共享内存:由一个进程创建,但多个进程都可以访问。往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
套接字:套解字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程 通信。

**2.线程和进程的区别;(一定要背下来,并且能够结合自己的项目行进阐述)
线程是指进程内的一个执行单元,也是进程内的可调用实体,与进程的区别:
(1)调度:线程作为调度和分配的基本单元,进程作为拥有资源的基本单位;
(2)并发性:不仅进程之间可以并发执行,同一个进程之间的多个线程也可以并发执行;
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源但可以访问隶属于进程的资源;
(4)系统开销:在创建或撤销进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤销线程时的开销;

3、内核态和用户态
为什么要有用户态和内核态?
由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 – 用户态 和 内核态

运行于用户态的进程可以执行的操作和访问的资源都会受到极大的限制,而运行在内核态的进程则可以执行任何操作并且在资源的使用上没有限制。很多程序开始时运行于用户态,但在执行的过程中,一些操作需要在内核权限下才能执行,这就涉及到一个从用户态切换到内核态的过程。这种过程需要采用一种机制,这种机制就是系统调用。

4、多进程与多线程的区别?
数据共享:进程数据分开,共享复杂,同步简单;线程共享进程数据,同步复杂;
开 销:内存占用多,切换开销大,CPU利用率低;线程内存占用少,切换开销小,CPU利用率高;
复 杂 度:进程编程简单,调试简单;线程编程、调试较复杂;
互相影响:进程之间相互独立,不会互相影响;线程之间联系密切,一个线程挂掉可能导致整个进程挂掉;
分 布 式:进程适用于多机,多核;线程适用于多核分布式。

5、多进程编程的优缺点?
优点:当多进程中的一个进程出现异常,其他进程不受任何影响。可靠性高。
缺点:存在进程互斥情况。当多个进程需要某一共享资源的时候,任何时候只允许一个进程使用。其他进程要使用的时候只能进行等待,等到资源被释放后才可以使用。占用内存多。
孤儿进程的存在 是因为 父进程先于子进程退出,那么子进程会变成孤儿进程。孤儿进程最后会被init接管,而僵尸进程会继续占用资源
僵尸进程的存在 是因为 子进程退出后,父进程并没有调用wait()或者 waitpid(),子进程的描述符还保留在系统中
它需要它的父进程来为它收尸,如果他的父进程没调用wait或waitpid()等待子进程结束,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动 会接手这个子进程,为它收尸,它还是能被清除的

6、谈谈你对进程的理解,内核是如何管理进程的?
首先,进程是资源分配的基本单位,一个程序就是一个进程。进程有三个状态。执行状态,阻塞状态,就绪状态。内核调度器通过不同的调度方法选择最值得运行的进程。
执行状态:进程正在占用CPU
阻塞状态:正在执行的进程,由于等待某个事件的发生而无法执行
就绪状态:进程已经具备执行一切的条件,等待分配CPU的处理时间片
Linux进程结构一般由三部分组成:代码段、数据段和堆栈段
●代码段:用于存放程序代码的数据:如果机器中有多个进程运行相同的一个程序,那么它们就可以使用同一段代码
●数据段:存放程序的全局变量、常量和静态变量
●堆栈段:栈用于函数调用,存放函数的参数、函数内部定义的局部变量。堆栈段中还包括了进程控制块(Process Control Block,PCB)
PCB处于进程核心堆栈的底部,不需要额外分配空间。PCB是进程存在的唯一标识,系统通过PCB的存在而感知进程的存在。系统通过PCB对进程进行管理和调度。PCB包括创建进程、执行程序、退出进程以及改变进程的优先级等

**7、什么是进程死锁?操作进程死锁的原因是什么?
什么是死锁:
所谓死锁:是指多个进程在运行过程中因争夺资源而造成的一种僵局。
产生死锁的原因:
(1)竞争资源:当系统中多个进程使用共享资源,并且资源不足以满足需要,会引起进程对资源的竞争而产生死锁。
(2)进程间推进的顺序非法:请求和释放资源的顺序不当,也同样会导致产生进程死锁。
产生死锁的必要条件:
(1)互斥条件:一个资源每次只能被一个进程使用
(2)请求和保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
(3)不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
(4)环路等待条件:若干资源之间形成一种头尾相接的循环等待资源关系
处理死锁的方法:
(1)预防死锁:
事先预防,破坏产生死锁的四个必要条件之一。
●摒弃“请求与保持条件”:
进程在申请资源时,是一次性的。
如何摒弃“请求”:当进程来时,一次性分配所有的资源(如果系统满足),这样就不会再有“请求”了。
如何摒弃“保持”:只要有一个资源得不到分配,也不给这个进程分配其他的资源。
●摒弃“不剥夺条件”:如果一个进程,获得了部分资源,但得不到其他资源,这时,它释放自己 所占用的资源。
●摒弃“环路等待条件”:把资源排序,当进程申请资源时,按序申请。
(2)避免死锁:
●检测死锁:
就是如果发生死锁了,系统可以通过检测机构发现死锁,并精确确定与死锁有关的进程和资源。
●解除死锁:
这是与检测死锁配套使用。当检测到系统中已经发生了死锁,要将进程从死锁状态中解脱出来。常用的方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已经处于阻塞状态的进程,使之转换为就绪状态,以继续运行。

9、系统调用与库函数的区别?
(1)系统调用是最底层的调用,是面向硬件的。而库函数的调用是面向应用开发的,相当于应用程序的API接口。
(2)各个操作系统的系统调用是不同的,因此系统调用一般没有跨操作系统的可移植性,而库函数在所有的ANSIC编译器中,C库是相同的,所以库函数的移植性很好。
(3)库函数属于过程调用,调用开销较小;系统调用需要用户空间和内核上下文环境间切换,开销较大。
(4)库函数调用函数库中的一段程序,这段程序最终还是通过系统调用实现;系统调用调用的是系统内核的服务
8、多线程之间的通信方式:
1.全局变量 2.消息队列 3.事件
同步方式:
1.互斥锁 2.信号灯 3.条件变量

9、进程
PCB是系统对进程的唯一标识,进程标识符PID,父进程标识符PPID,
获取本进程ID
pid_t getpid(void)
获取父进程ID
pid_t getppid(void)

创建多线程
pthread_create
线程分离
pthread_detach(pthread_self());
1.linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。
2.unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.
3.其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦

创建子进程
pid_t fork(void)
fork被调用一次,返回两次
1、在父进程中,fork返回新创建的子进程的PID;
2、在子进程中,fork返回0;
3、如果出现错误,fork返回一个负值
注意:

  1. fork完后创建两个进程,每个进程从fork()返回继续执行
  2. 两个进程执行相同的代码段,但都有各自的栈区,堆区,数据段
  3. fork完后两个进程哪个先执行不确定
    pid_t vfork(void);

区别:1. fork:子进程拷贝父进程的数据段
vfork:子进程与父进程共享数据段

       2. fork:父、子进程的执行次序不确定  
         vfork:子进程先运行,父进程后运行

进程等待
pid_t wait(int *status);
pid = wait(NULL);
如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD

进程退出
_exit立即进入内核
exit先执行一些清理处理(调用各终止处理程序、关闭所有标准I/O流等),然后进入内核。
#include <stdlib.h>
void exit(int status);
#include <unistd.h>
void _exit(int status);
(echo $?正常退出为0,非正常退出打印退出码)

10、熟知一些命令的作用,比如说用vi操作多个文件之类的;
man 对你熟悉或不熟悉的命令提供帮助解释 chmod 权限修改
ls 查看目录、文件的属性、列举相应目录下文件 clear 清屏
cp 拷贝文件 data 显示当前时间
rm 删除文件和目录 mount 加载一个硬件设备
mv 移走目录或者改文件名 su 在不退出登陆的情况下,切换用户
cd 改变当前目录 whoami 确认自己身份
pwd 查看当前所在目录完整路径 whereis查询命令所在目录及帮助文档所在目录
cat 将文件中内容显示出来;一直打印出来 which:查询该命令所在目录(类似whereis)
more 将文件中的内容显示出来;分屏显示 id:打印出自己的UID以及GID
grep 文本内容搜索;
find 文件或者目录名以及权限属主等匹配搜索 kill 可以杀死某个正在进行或者已经是dest状态的进程
passwd 可以设置口令 history 用户用过的命令
!! 执行最近一次的命令 mkdir命令
tar 解压命令 finger 可以让使用者查询一些其他使用者的资料

11、makefile怎么用?就是具体怎么写,依赖是什么?
makefile的一个基本格式:
目标:依赖文件
tab 命令
“目标”:是你要生成的最终文件
“依赖”:(依赖文件的任一处改动将导致已存在的目标文件过期)
简单来说:
依赖的作用就是决定目标是否过期,是否需要重新编译

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值