解析:(1)进程是资源的分配和调度的一个独立单元,狭义上来说,进程是指程序执行的一个实例。而线程是CPU调度的基本单元,是进程的一个实体,是程序执行的最小单位。
(2)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进行至少包括一个线程。
(3)进程的创建调用fork或者vfork,而线程的创建调用pthread_create,进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
(4)线程是轻量级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的
(5)线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源
(6)线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志
(7)进程拥有独立的堆栈空间和数据段,内存需要给进程分配独立的地址空间,开销大线程有独立的堆栈空间但是共享数据段,开销小,切换速率快。相对的,进程的独立性表明进程的安全性高。
(8)也体现了通信上,进程因为是独立的互不干扰的,进程的通信较为复杂,有管道消息队列共享内存,socket,信号等方式,而线程因为共享数据段通信机制方便快速。
2、死锁?死锁产生的原因?死锁的必要条件?怎么处理死锁?
所谓死锁,是指多个进程循环等待它方占有的资源而无限期地僵持下去的局面
1〉互斥条件。即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有。这种独占资源如 CD-ROM驱动器,打印机等等,必须在占有该资源的进程主动释放它之后,其它进程才能占有该资源。这是由资源本身的 属性所决定的。如独木桥就是一种独占资源,两方的人不能同时过桥。
〈2〉不可抢占条件。进程所获得的资源在未使用完毕之前,资源申请者不能强行地从资源占有者手中夺取资源,而只能 由该资源的占有者进程自行释放。如过独木桥的人不能强迫对方后退,也不能非法地将对方推下桥,必须是桥上的人自己 过桥后空出桥面(即主动释放占有资源),对方的人才能过桥。
〈3〉占有且申请条件。进程至少已经占有一个资源,但又申请新的资源;由于该资源已被另外进程占有,此时该进程阻 塞;但是,它在等待新资源之时,仍继续占用已占有的资源。还以过独木桥为例,甲乙两人在桥上相遇。甲走过一段桥面 (即占有了一些资源),还需要走其余的桥面(申请新的资源),但那部分桥面被乙占有(乙走过一段桥面)。甲过不去, 前进不能,又不后退;乙也处于同样的状况。
〈4〉循环等待条件。存在一个进程等待序列{P1,P2,...,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一源,......,而Pn等待P1所占有的的某一资源,形成一个进程循环等待环。就像前面的过独木桥问题,甲等待乙占有的桥面,而乙又等待甲占有的桥面,从而彼此循环等待。
解析:(--)相互等待资源而产生的一种僵持状态,如果没有外力的干预将一直持续这个状态(--)系统资源不足、相互竞争资源、请求资源顺序不当
(2)互斥、不可抢占、循环等待、请求与保持
(3)因为互斥是不可改变的,所以只能破坏其他三个条件中的一个来解除死锁,方法:剥夺资源、杀死其中一个线程
3、Windows内存管理方式:段存储、页存储、段页存储。Linux的内存管理:
解析:页框管理,内核必须记住每个页框当前的状态。
非一致性访问:我们习惯认为计算机是一种均匀共享的资源,而在这种模型中,给定CPU对不同内存单元的访问时间可能不一样。
内存管理区
内存池是Linux2.6的一个新特性。一个内存池允许一个内核成分,如块设备子系统,仅在内存不足的情况下分配一些动态内存来使用。一个内存池常常加在分配器之上
非连续内存去管理。
4、进程的几种状态?解析:(1)run(运行状态):正在运行的进程或在等待队列中对待的进程,等待的进程只要以得到cpu就可以运行
(2)Sleep(可中断休眠状态):相当于阻塞或在等待的状态
(3)D(不可中断休眠状态):在磁盘上的进程
(4)T(停止状态):这中状态无法直观的看见,因为是进程停止后就释放了资源,所以不会留在linux中
(5)Z(僵尸状态):子进程先与父进程结束,但父进程没有调用wait或waitpid来回收子进程的资源,所以子进程就成 了僵尸进程,如果父进程结束后任然没有回收子进程的资源,那么1号进程将回收
5、IPC通信方式?
解析:(1)管道(匿名管道(pipe亲缘关系的进程通信)、命名管道(mkfifo/mknod))
(2)消息队列:是基于消息的、用无亲缘关系的进程间通信,主要函数:msgget、msgsend、msgrecv、msgctl
(3)信号量:相当于一把互斥锁,通过p、v操作,主要函数:semget、semop、semctl
(4)共享内存:是进程间通信速度最快的,所以用经常是集合信号量或互斥锁来实现同步,shmget、shmat、shmdt、shmctl
(1)、管道(pipe):管道可用于具有亲缘关系的进程间的通信,是一种半双工的方式,数据只能单向流动,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)、命名管道(named pipe):命名管道克服了管道没有名字的限制,同时除了具有管道的功能外(也是半双工),它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
(3)、信号(signal):信号是比较复杂的通信方式,用于通知接收进程有某种事件发生了,除了进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
(4)、消息队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
(5)、共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(6)、内存映射:内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)、信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)、套接字(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
解析:是将进程部分装入内存中,从而能实现一个很大的程序能在一个比它小的内存中运行,它的主要实现是靠程序的换进换出来实现的,因为内存中0~3G是用户使用,3~4G才是内存使用,通过映射来实现来进行逻辑地址到物理地址的映射
7、虚拟地址、逻辑地址、线性地址、物理地址的区别?
解析: 分段机制把一个逻辑地址转换为线性地址;接着,分页机制把一个线性地址转换为物理地址。
(1)虚拟地址:虚拟内存映射出来的地址
(2)逻辑地址:程序的段加偏移量形成的,C/C++程序中取地址求出来的地址就是逻辑地址
(3)线性地址:是逻辑地址到物理地址的中间层,只有启动分页机制的时候才有线性地址,如果没有分页机制,那么线性地址就是物理地址
(4)物理地址:是内存中实实在在存在的硬件地址,
逻辑地址(启动分段)--》线性地址(启动分页)--》物理地址
如果用户传递的信息较少.或是需要通过信号来触发某些行为.前文提到的软中断信号机制不失为一种简捷有效的进程间通信方式.但若是进程间要求传递的信息量比较大或者进程间存在交换数据的要求,那就需要考虑别的通信方式了。无名管道简单方便.但局限于单向通信的工作方式.并且只能在创建它的进程及其子孙进程之间实现管道的共享:有名管道虽然可以提供给任意关系的进程使用.但是由于其长期存在于系统之中,使用不当容易出错.所以普通用户一般不建议使用。消息缓冲可以不再局限于父子进程.而允许任意进程通过共享消息队列来实现进程间通信.并由系统调用函数来实现消息发送和接收之间的同步.从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题.使用方便,但是消息队列中信息的复制需要额外消耗CPU的时间.不适宜于信息量大或操作频繁的场合。共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优点。但是共享内存的通信方式是通过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的.因此,这些进程之间的读写操作的同步问题操作系统无法实现。必须由各进程利用其他同步工具解决。另外,由于内存实体存在于计算机系统中.所以只能由处于同一个计算机系统中的诸进程共享,不方便网络通信。不同的进程通信方式有不同的优点和缺点.因此.对于不同的应用问题,要根据问题本身的情况来选择进程间的通信方式。
最初Unix IPC包括:管道、FIFO、信号。System V IPC包括:System V消息队列、System V信号灯、System V共享内存区。由于Unix版本的多样性,电子电气工程协会(IEEE)开发了一个独立的Unix标准,这个新的ANSI Unix标准被称为计算机环境的可移植性操作系统界面(PSOIX)。现有大部分Unix和流行版本都是遵循POSIX标准的,而Linux从一开始就遵循POSIX标准。Posix IPC包括: Posix消息队列、Posix信号灯、Posix共享内存区。 所以目前linux上面支持的IPC主要包括四类:
1. UNIX早期IPC:管道、FIFO、信号;
2. system V IPC:System V消息队列、System V信号灯、System V共享内存区;
3. Posix IPC: Posix消息队列、Posix信号灯、Posix共享内存区;
4. 基于socket的IPC;
我们这一系列没有讲述信号灯相关内容,是因为信号灯是进程间以及同一进程不同线程之间的一种同步方式,我们这一系列把精力主要放在进程之间信息的交互上面,而同步与互斥的内容放在另一个系列,这样更便于知识的细化归类,各个击破。其实同步与互斥是进程间通信的一个很重要的内容,所以我们会立即在下一个系列详细讲解同步与互斥的内容。
下面分析一下我们这一系列文章各种IPC的特点:
1. socket
a、使用socket通信的方式实现起来简单,可以使用因特网域和UNIX域来实现,使用因特网域可以实现不同主机之间的进出通信。
b、该方式自身携带同步机制,不需要额外的方式来辅助实现同步。
c、随进程持续。
2. 共享内存
a、最快的一种通信方式,多个进程可同时访问同一片内存空间,相对其他方式来说具有更少的数据拷贝,效率较高。
b、需要结合信号灯或其他方式来实现多个进程间同步,自身不具备同步机制。
c、随内核持续,相比于随进程持续生命力更强。
3. 管道
a、较早的一种通信方式,缺点明显:只能用于有亲缘关系进程之间的通信;只支持单向数据流,如果要双向通信需要多创建一个管道来实现。
b、自身具备同步机制。
c、随进程持续。
4. FIFO
a、是有名管道,所以支持没有亲缘关系的进程通信。和共享内存类似,提供一个路径名字将各个无亲缘关系的进程关联起来。但是也需要创建两个描述符来实现双向通信。
b、自身具备同步机制。
c、随进程持续。
5. 信号
a、这种通信可携带的信息极少。不适合需要经常携带数据的通信。
b、不具备同步机制,类似于中断,什么时候产生信号,进程是不知道的。
6. 消息队列
a、与共享内存和FIFO类似,使用一个路径名来实现各个无亲缘关系进程之间的通信。消息队列相比于其他方式有很多优点:它提供有格式的字节流,减少了开发人员的工作量;消息具有类型(system V)或优先级(posix)。其他方式都没有这些优点。
b、具备同步机制。
c、随内核持续。
子进程继承父进程
用户号UIDs和用户组号GIDs
环境Environment
堆栈
共享内存
打开文件的描述符
执行时关闭(Close-on-exec)标志
信号(Signal)控制设定
进程组号
当前工作目录
根目录
文件方式创建屏蔽字
资源限制
控制终端
子进程独有
进程号PID
不同的父进程号
自己的文件描述符和目录流的拷贝
子进程不继承父进程的进程正文(text),数据和其他锁定内存(memory locks)
不继承异步输入和输出
父进程和子进程拥有独立的地址空间和PID参数。