[校招准备]之:操作系统——进程与线程

操作系统中进程与线程的概念比较抽象,其实是挺不容易掌握的。在《现代操作系统》一书的第二章有专门的介绍,并且这一部分是整部书最重要的课程。我还记得我们老师说,“掌握了进程与线程的概念,基本就掌握了操作系统的百分之六七十“。现在回想起来有点后悔自己当初怎么没有好好把握机会认真学习这一块。但是为时不晚,这个时候学总比未来学好,下面开始一边学习《现代操作系统》此篇幅的知识一边做笔记。

进程

现在考虑直邮一个用户的pc。当启动系统的时候,会秘密启动许多进程。比如,启动一个进程用来等待进入的电子邮件;或者启动另一个防病毒进程周期性检查是否有新的有效的病毒定义。另外,某个用户进程也许会在所有用户上网的时候打印文件等。所有这些活动需要管理,于是一个支持多进程的多道程序系统就显得很有用处。

一个进程就是一个正在执行程序的实例,包括程序计数器、寄存器和变量的当前值。从概念上说,每个进程拥有自己饿虚拟cpu,当然,实际上真正的cpu在各个进程之间来回切换。而这种快速的切换称为多道程序设计。

另外,进程和程序之间的区别是微妙的,但非常重要。有一个关键的思想:一个进程是某种类型的活动,它有程序、输入、输出以及状态。单个处理器可以被若干进程共享,它使用某种调度算法决定何时停止一个进程的工作,并且转而为另一个进程提供服务。

有什么事件可以导致进程的创建的呢?
4种:
1)系统初始化。
2)执行了正在运行的进程所调用的进程创建系统调用
3)用户请求创建了一个新进程
4)一个批处理作业的初始化

从技术上看,所有这些情形中,新进程都是由于一个已存在的进程执行了一个用于创建进程的系统调用而创建的。

创建进程

在unix系统中,只有一个系统调用可以用来创建新进程:fork。这个系统调用会创建一个与调用进程相同的副本。在调用了fork之后,这两个进程(父与子进程)拥有相同的存储映像、同样的环境字符串和同样的打开文件。这就是全部情形。通常,子进程接着执行execve或一个类似的系统调用,以修改其存储映像并运行一个新的程序。

记住,进程创建之后,父进程和子进程有各自不同的地址空间,如果其中某个进程在其地址空间中修改了一个字,这个修改对其他进程而言是不可见的。在unix中,子进程的初始地址空间是父进程的一个副本,但是这里涉及两个不同的地址空间,不可写的内存区是共享的(某些unix的实现使程序正文在两者之间共享,因为它不能被修改)。但是,对于一个新创建的进程而言,确实可能共享其创建者的其他资源。

   小知识:停留在后台处理诸如电子邮件、web页面、新闻、打印之类活动的进程称为守护进程。

终止进程

通常由下列条件引起:
1)正常退出(自愿的)——exit
2)出错退出(自愿的)
3)严重错误(非自愿)
4)被其他进程杀死(非自愿)——kill

进程的层次结构

在unix中,进程和它的所有子女以及后裔共同组成一个进程组。当用户从键盘发出一个信号时,该信号被送给当前与键盘相关的进程组中的所有成员(它们通常是在当前窗口创建的所有活动进程)。每个进程可以分别捕获该信号、忽略该信号或采取默认的动作,即被该信号被杀死。

一个例子用于说明进程层次的作用。考虑unix在启动时如何初始化自己。一个称为init的特殊进程出现在启动映像中。当它开始运行时,读入一个说明终端数量的文件。接着,为每个终端创建一个新进程。这些进程等待用户登陆。如果有一个用户登录成功,该登录进程就执行一个shell准备接收命令。所接收的这些命令会启动更多的进程,以此类推。这样,在整个系统中,所有的进程都属于以init为根的一棵树。

进程的状态

当一个进程在逻辑上不能继续运行时,它就会被阻塞,典型的例子是它在等待可以使用的输入。还可能有这样的情况:一个概念上能够运行的进程被迫停止,因为操作系统调度另一个进程占用了cpu。

以上两种情况其实是完全不同的。第一种情况,进程挂起是程序自身固有的原因(键入用户命令行之前无法执行命令)。第二种情况是由系统技术上的原因引起(没有足够的cpu,所以不能使每个进程都有一台它私用的处理器)

三种状态:运行态(该进程实际占用cpu),就绪态(可运行,但因为其他进程正在运行而暂时停止),阻塞态(除非某种外部事件发生,否则进程不能运行)

进程的实现

为了实现进程模型,操作系统维护着一张表格(一个结构数组),即进程表。每个进程占用一个进程表项。该表项包含了进程状态的重要信息,包括程序计数器、堆栈指针、内存分配状况、所打开的文件的状态、账号和调用信息,以及其他在进程由运行态转换到就绪态或阻塞态时必须保存的信息,从而保证该进程随后能再次启动就像从未被中断过一样。

所有的中断都从保存寄存器开始,对于当前进程而言,通常是在进程表项中。

线程

传统os中,每个进程有一个地址空间和一个控制线程。不过经常存在同一个地址空间中准并行运行多个控制线程的情形,这些线程就像(差不多)分离的进程(共享的地址空间除外)。

线程的使用

产生线程的必要性:
1)在许多应用中同时发生着多种活动。有了多线程概念,加入了一种新的元素:并行实体共享同一个地址空间和所有可用数据的能力。而这正是多进程模型无法表达的。

2)线程比进程更轻量级,比进程更快创建更容易撤销。

3)性能。若多个线程都是cpu密集型的,那么并不能获得性能上的增强,但是如果存在大量计算和大量io处理,拥有多线程允许这些活动彼此重叠进行,会加快应用程序执行的速度。

多线程提供一种解决方案,有关进程可以用一个输入线程、一个处理线程和一个输出线程构造。输入线程把数据读入到输入缓冲区中;处理线程从输入缓冲区中取出数据,处理数据,并把结果放到输出缓冲区中;输出线程把这些结果写道磁盘上。

经典线程模型

进程用于把资源集中到一起,线程则是在cpu上被调度执行的实体。多线程共享同一个地址空间和其他资源,多个进程共享物理内存、磁盘、打印机和其他资源。

多线程进程在单cpu系统中运行时,线程轮流运行。其实这样的话和多进程执行类似的。cpu在线程之间的快速切换,系统制造了不同的顺序进程并行运行的假象。但是呢,进程中的不同线程不像不同进程之间那样存在很大的独立性。所有的线程都有完全一样的地址空间也就意味着它们共享同样的全局变量。又因为各个线程可以访问进程地址空间中的每一个内存地址,所以一个线程可以读、写或甚至清除另一个线程的堆栈。线程之间时没有保护的,原因是1)不可能。2)也没有必要。因为线程是为了合作而不是竞争。

所以说对于三个没有关系的线程而言,使用每个分别存在于各个进程的方法;而如果要三个线程实际完成同一个作业,最好就存在于同一个进程中。

以上是摘抄的部分书本内容。


好的,讲了一些七七八八的零散入门知识,如果要深入,最好的还是把那本书的第二章从头到尾仔仔细细看一遍。而我目前想理解的重点(虽然前面已经这里那里的讲了一些),其实是进程与线程,到底有一个什么的区别,这也是面试常常会问的问题。所以针对之前看书的内容大致理出了这么一个思路:


进程与线程总结

1.进程和线程

1.1 概述

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

线程则是进程的一个实体,是cpu调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己呢基本上是不拥有系统资源的,只拥有一点在运行中必不可少的资源(比如说程序计数器、一组寄存器和栈),但是它可以与同属于一个进程的其它线程共享进程所拥有的全部资源。

一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间还可以并发执行。

相对进程而言,线程是一个更加接近于知兴替的一个概念,它可以与同进程的其它线程共享数据,但是却拥有自己的栈空间、拥有独立的执行序列。

在串行程序基础上引入线程和进程是为了提高程序的并发度,从而提高程序运行效率和响应时间。

1.2 区别

其实呢,二者的主要差别还是在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其他进程产生影响。而线程知识一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但是,线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程程序要比多线程程序健壮,但是在进程切换时,耗费资源较大,效率要差一些。不过对于一些要求同时进行又要共享某些变量的并发操作,只能用线程,不能用进程。

1)简而言之,一个程序至少有有一个进程,一个进程至少有一个线程.

2)线程的划分尺度是小于进程的多,使得多线程程序的并发性高

3)另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率

4)线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程是不能够独立执行的,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5)从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但是操作系统并没有将多个线程 看作是多个独立的应用,来实现进程的调度和管理以及资源分配。这就是线程和进程的重要区别

1.3 优点和缺点

线程和进程在使用上各有优缺点:线程执行开销小,但是不利于资源的管理和保护;而进程相反。同时,线程适合于在smp机器上运行,而进程则可以跨机器迁移。

2. 多进程,多线程

2.1 概述

进程就是一个程序运行的时候被cpu抽象出来的,一个程序运行后被抽象为一个进程,但是线程是从一个进程里边分割出来的,由于cpu处理进程的时候是采用时间片轮转方式,所以要把一个大个的进程分割成多个线程,例如:网际快车中文件分成100个部分、10个线程,那么文件就被分成了10份来同时下载,1~10占一个线程,11~20占一个线程,以此类推,线程越多,文件就被分的越多,同时下载,当然速度也就越快。

进程是程序在计算机上的一次执行活动,当你运行一个程序你就启动了一个进程。显然程序只是一组指令的有序集合,本身是没有任何运行的含义,只是一个静态的实体。而进程不同,它是程序在某个数据集赏的执行,是一个动态的实体。它因创建而产生,因调度而运行,因等待资源或时间而被处于等待状态,因完成任务而被撤销,反映了一个程序在一定的数据集上运行的全部动态过程。进程是操作系统分配资源的单位。在Windows下,进程又被细化为线程,也就是一个进程下有多个能独立运行的更小的单位。线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位。线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

线程和进程的关系:线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除。线程可与属于同一进程的其它线程共享进程所拥有的全部资源,但是其本身基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和栈)。

在同一个时间里,同一个计算机系统中如果允许两个或两个以上的进程处于运行状态,这便是多任务。现代的操作系统几乎都是多任务操作系统,能够同时管理多个进程的运行。 多任务带来的好处是明显的,比如你可以边听mp3边上网,与此同时甚至可以将下载的文档打印出来,而这些任务之间丝毫不会相互干扰。那么这里就涉及到并行的问题,俗话说,一心不能二用,这对计算机也一样,原则上一个CPU只能分配给一个进程,以便运行这个进程。我们通常使用的计算机中只有一个CPU,也就是说只有一颗心,要让它一心多用,同时运行多个进程,就必须使用并发技术。实现并发技术其实相当复杂,最容易理解的是“时间片轮转进程调度算法”,它的思想简单介绍如下:在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如10毫秒),这样用户根本感觉不出来CPU是在轮流为多个进程服务,就好象所有的进程都在不间断地运行一样。但实际上在任何一个时间内有且仅有一个进程占有CPU。

但是如果一台计算机有多个CPU,情况就不同了,如果进程数小于CPU数,则不同的进程可以分配给不同的CPU来运行,这样,多个进程就是真正同时运行的,这便是并行。但如果进程数大于CPU数,则仍然需要使用并发技术。

在Windows中,进行CPU分配是以线程为单位的,一个进程可能由多个线程组成,这时情况更加复杂,但简单地说,有如下关系:

总线程数<= CPU数量:并行运行
总线程数> CPU数量:并发运行

并行运行的效率显然高于并发运行,所以在多CPU的计算机中,多任务的效率比较高。但是,如果在多CPU计算机中只运行一个进程(线程),就没办法发挥多CPU的优势。

所以,多任务操作系统(如Windows)的基本原理是:

操作系统将CPU的时间片分配给多个线程,每个线程在操作系统指定的时间片内完成(注意,这里的多个线程是分属于不同进程的).操作系统不断的从一个线程的执行切换到另一个线程的执行,如此往复,宏观上看来,就好像是多个线程在一起执行.由于这多个线程分属于不同的进程,因此在我们看来,就好像是多个进程在同时执行,这样就实现了多任务.

2.2 分类

根据进程与线程的设置,操作系统大致分为如下类型:
(1) 单进程、单线程,MS-DOS大致是这种操作系统;
(2) 多进程、单线程,多数UNIX(及类UNIX的LINUX)是这种操作系统;
(3) 多进程、多线程,Win32(Windows NT/2000/XP等)、Solaris 2.x和OS/2都是这种操作系统;
(4) 单进程、多线程,VxWorks是这种操作系统。

2.3 引入线程带来的好处:

(1) 在进程内创建、终止线程比创建、终止进程要快;
(2) 同一进程内的线程间切换比进程间的切换要快,尤其是用户级线程间的切换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值