进程和线程的区别

来源:互联网 发布:linux zip 解压乱码 编辑:程序博客网 时间:2024/06/08 12:50

面试中被问到几率最大的问题就是进程和线程的区别,本篇就聊聊关于进程和线程的事情吧奋斗


一、定义

进程:一个正在执行中的程序,或者一个正在计算机上执行的程序实例。进程是系统进行资源分配和调度的基本单位。


进程四要素

1、可供执行的程序

2、专用的系统堆栈空间

3、在内核中的task_struct数据结构(户口),记录着进程所占的各项资源

3、独立的用户空间


线程:是进程中的一个执行路径。是CPU调度和分派的基本单位,是比进程还小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一些在运行中必不可少的资源(程序计数器,一组寄存器和栈)但是它可以和同属于一个进程的其它线程共享进程所拥有的全部资源。


线程必须具备的条件

1、可供执行的程序

2、专用的系统堆栈空间

3、在内核中的task_struct数据结构


完全没有用户空间的称为内核线程,共享用户空间的称为用户线程。



用户线程:有关线程管理的所有工作都由应用程序完成,内核没有意识到有线程的存在。当进程中的线程发生阻塞时,控制权被交给内核,内核将该进程的状态设置为阻塞态,并切换另一进程运行。因此,用户线程阻塞会导致进程阻塞


用户级线程的优点

<1>由于所有线程管理数据结构都在一个进程的用户地址空间,线程切换不需要内核模式特权,进程不需要为了线程管理而切换到内核模式,节省了在两种模式之间切换的开销。

<2>调用可以是应用程序专有的。一个应用程序可能倾向于简单的轮询调度算法,而另一个进程可能倾向于基于优先级的调度算法。调度算法可以去适应应用程序,而不会扰乱底层的操作系统的调度器。

<3>用户级线程可以在任何操作系统中运行,不需要对底层内核进行修改以支持用户级线程。


用户级线程的缺点

<1>当用户级线程执行一个系统调用时,不仅这个线程会被阻塞,进程中的所有线程都会被阻塞。

<2>一个多线程应用程序不能利用多处理技术,内核一次只把一个进程分配给一个处理器,因此一个进程中只有一个线程可以执行。


内核线程:有关线程的管理的工作都是由内核完成的,应用程序部分没有进行线程管理的代码,只有一个到内核级线程设施的应用程序接口。


内核线程的点:

<1>内核可以把同一个进程中的多个线程调度到多个处理器中。

<2>如果进程中的一个线程被阻塞,内核可以调度同一个进程中的另一个线程

<3>内核例程自身也可以使用多线程。


内核线程的点:

<1>由于操作系统控制了内核线程的数量,所以用户线程的线程数量也受到影响

<2>用户线程切换时也要切换内核线程,内核线程调度时,上下文切换消耗较大,导致用户线程的执行效率下降


用户线程和内核线程的组合

线程创建完全在用户空间完成,线程的调度和同步也在应用程序中进行。一个应用程序中的多个用户级线程被映射到一些内核级线程上。同一个应用程序的多个线程可以在多个处理器上并行的运行,一个用户线程阻塞并不会导致所有用户线程阻塞,因为此外还有别的线程可被调度执行。也不会会导致进程阻塞


线程的状态 


线程的主要状态有:运行——阻塞——就绪 
挂起态是基于进程的状态概念,对线程没有实际意义。
当进程被换出内存(挂起)时,进程内的所有线程都被换出内存。

与线程状态有关的几种基本操作: 
派生:一般情况下,当产生一个新进程的时候,同时为该进程产生了一个线程,线程可在同一进程中产生其他线程,新线程将拥有自己的栈空间和寄存器上下文,新线程被放置在就绪队列中。

阻塞:当线程需要等待某一时间时,它将被阻塞,保存线程上下文信息,处理器转而处理同一进程或者其他进程的就绪线程。

解除阻塞:当阻塞线程的事件发生时,该线程被转移到就绪队列中。

结束:当一个线程运行完成时,其寄存器上下文和栈都被释放。


二、进程和线程的区别

进程和线程的本质区别进程有独立的用户空间,线程没有独立的用户空间


(1)一个程序至少有一个进程,一个进程至少有一个线程;

(2)进程是系统进行资源分配和调度的基本单位,线程是CPU调度和分派的基本单位,真正在CPU上执行的是线程 

(3)线程执行中,需要协作同步。进程之间要通过进程间通信的方法实现同步;

(4)系统分配资源给进程,同一进程中的线程共享进程中的资源,从而极大地提高了程序的运行效率;但是线程也有自己的私有存储空间(栈空间、一组寄存器)。

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

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

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

(8)Linux系统上,创建线程的函数pthread_create底层调用的是clone,而fork,vfork,clone这类创建进程/线程的函数实际调用的系统API都是do_fork()。


三、多线程的优点

<1>线程之间切换比进程之间花费的时间少,效率高

在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,开销大。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间。进程的切换需用户态和内核态之间的切换,所以线程之间切换比进程之间花费的时间少,效率高。

<2>线程间方便的通信机制

对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。


除了以上所说的优点外,不和进程比较,多线程程序作为一种多任务、并发的工作方式,当然有以下的优点:

1、提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。

2、使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。

3、改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。

原创粉丝点击