1.进程和线程的区别。
一个程序至少有一个进程,一个进程至少有一个线程
(1)进程是系统进行资源分配的基本单位,有独立的内存地址空间;线程是CPU调度的基本单位,没有单独的地址空间,有独立的栈,寄存器,程序计数器,局部变量等。
(2)创建进程的开销大,包括创建虚拟地址空间等需要大量的系统资源;创建线程开销小,基本上只有一个内核对象和一个堆栈。
(3)一个进程无法直接访问另一个进程的资源;同一进程内的多个线程共享进程的资源。
(4)进程切换开销大,线程切换开销小;进程间通信开销大,进程间通信开销小。
(5)线程属于进程,不能独立运行。每个进程至少有一个线程,成为主线程。
详细描述:
进程可以认为是程序执行时的一个实例。进程是系统进行资源分配的独立实体, 且每个进程拥有独立的地址空间。一个进程无法直接访问另一个进程的变量和数据结构, 如果希望让一个进程访问另一个进程的资源,需要使用进程间通信,比如:管道,文件, 套接字等。
一个进程可以拥有多个线程,每个线程使用其所属进程的栈空间。 线程与进程的一个主要区别是,同一进程内的多个线程会共享部分状态, 多个线程可以读写同一块内存(一个进程无法直接访问另一进程的内存)。同时, 每个线程还拥有自己的寄存器和栈,其它线程可以读写这些栈内存。
线程是进程的一个特定执行路径。当一个线程修改了进程中的资源, 它的兄弟线程可以立即看到这种变化。
生活中实例:
进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。
一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人。一个进程可以包括多个线程。
车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。
可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。
一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域
还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。
这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做"信号量"(Semaphore),用来保证多个线程不会互相冲突。
不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。
2.死锁的必要条件,怎么处理死锁。
1 )互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2 )请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3 )不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4 )环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
解决死锁的方法:
(1)资源剥夺法:当发现死锁后,从其他进程那里剥夺足够数量的资源给死锁进程,以解除死锁状态。
(2)撤销进程法:就是撤销全部死锁进程,使系统恢复到正常状态,这种做法付出代价太大。
3.Window内存管理方式:段存储,页存储,段页存储(非连续分配管理方式)。
段存储:操作系统为了让内存能够使用起来,将程序分成多个段:如主程序,变量集,函数库,动态数组,栈,然后将每个用户段放到内存空闲的地方。会产生内存碎片。
页存储:将内存的存储空间分成与页大小相等的区域,称为物理块或块。物理内存的分配就是分页。针对每个段内存请求,系统一页一页的分配给这个段。这样的好处是空间浪费很小。(什么是页?就是用户作业的地址空间被划分成若干大小相等的区域)
段页存储:用户希望分段,物理内存希望分页,这样操作系统就把结合起来用。
这就存在一个虚拟内存的问题。首先在虚拟内存(地址空间)上割出一段给用户程序,但是虚拟内存并不能真正往里面放东西,需要把虚拟内存再映射到物理内存上。(该操作是对用户透明的)
4.进程的几种状态。
三种基本状态。就绪,执行,阻塞
(1)就绪状态:当进程已分配到除CPU以外的所有必要的资源,只要获得处理机(CPU)便可立即执行。
(2)执行状态:当进程已经获得CPU,其程序正在处理机上执行,此时的进程状态就是执行状态。
(3)阻塞状态:正在执行的进程,由于等待某个事件发生而无法执行时,便放弃CPU而处于阻塞状态。
5.IPC几种通信方式。IPC=Inter-Process Communication(进程间通信)
有三种通信方式。共享存储器系统,消息传递系统和管道通信系统
(1)共享存储器系统:在共享存储器系统中,进程通过共享内存中的存储区来实现通信。为了实现通信,进程在进行通信前应向系统申请建立一个共享存储区,并指定该共享存储区的关键字。
(2)消息传递系统:在消息传递系统中,进程间的数据交换以消息为单位,程序员直接利用系统提供的一组通信命令(原语)来实现通信。
(3)管道通信系统:管道是用于连接读进程和写进程以实现它们之间通信的共享文件,向管道提供输入的发送进程(即写进程)以字符流形式将大量的数据送入管道,而接收管道输出的接收进程(即读进程)可以从管道中接收数据。
(4)套接字(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间的通信
6. 什么是虚拟内存。
实质就是让程序存在的地址空间和运行时用于存放程序的存储空间区分开。程序员可以在地址空间内编写程序,而不用完全考虑实际内存大小。在多道程序环境下,可以为每个用户程序建立一个虚拟存储器。
当然,虚拟存储器的容量也不是无限的,它的最大容量由计算机的地址结构来确定。
7. 虚拟地址、逻辑地址、线性地址、物理地址的区别。
(1)虚拟地址是由程序产生的由段选择符和段内偏移地址组成的地址。这两部分组成的地址并没有直接访问物理内存,而是要通过分段地址的变换处理后才会对应到相应的物理内存地址。
(2)逻辑地址指由程序产生的段内偏移地址。有时把逻辑地址当成虚拟地址,两者并没有明确的界限。逻辑地址在PCB中
(3)线性地址是指虚拟地址到物理地址变换的中间层, 是处理器可寻址的内存空间(称为线性地址空间)中的地址。程序代码会产生逻辑地址,或者说段中的偏移地址,加上相应段基址就生成了一个线性地址。如果启用了分页机制,那么线性地址可以再经过变换产生物理地址。若是没有采用分页机制,那么线性地址就是物理地址。
(4)物理地址是指现在 CPU 外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果。(逻辑地址+基地址=物理地址)
虚拟地址到物理地址的转换方法是体系结构相关的,一般分段与分页两种方式。以X86CPU为例:
分段分页都是支持的。内存管理单元负责从虚拟地址到物理地址的转化。逻辑地址是段标识+段内偏移 MMU(内存管理单元) 通过查询段表,可以把逻辑地址转换为线性地址。
如果CPU没有开启分页功能,线性地址就是物理地址;如果CPU开启了分页功能,MMU还需要查询业表来将线性地址转换为物理地址;
逻辑地址(段表)--------> 线性地址(页表)------------->物理地址。
映射是一种多对一的关系,即不同的逻辑地址可以映射到同一个线性地址上;
不同的线性地址也可以映射到同一个物理地址上。而且同一个线性地址在发生变化后,也可能被重新装载到另外一个物理地址上,所以这种多对一的关系也会随时间发生变化。