进程与线程

一、背景知识:

  进程的概念起源于操作系统,是操作系统最核心的概念。

  进程是对正在运行程序的一个抽象,操作系统的其它所有内容都是围绕进程的概念展开的。

  进程是操作系统提供的最古老也是最重要大的抽象概念之一。即使可以利用的cpu只有一个,也能保证支持伪并发的能力。将一个单独的cpu变成多个虚拟的cpu(多道技术:时间多路复用和空间多路复用+硬件上支持隔离),没有进程的抽象,现代计算机将不复存在。

  进程是正在运行的程序的抽象,但是并不等同于程序,程序是死的,只有运行后才有类进程的概念。一个进程又包含一个或多个线程,线程才是具体实施干活的。

二、进程

1、什么是进程:正在进行的一个过程或者说一个任务都是一个进程。如启动一个程序、执行一个命令等。

2、进程与程序的区别:程序仅仅只是一堆代买而已,而进程指的是程序的运行过程。

  需要强调的是:同一个程序执行两次,那也是两个进程,比如打开暴风影音,虽然都是同一个软件,但是一个可以播放苍井空,一个可以播放饭岛爱。

3、并发与并行:无论是并行还是并发,在用户看来都是‘同时’运行的,不管是进程还是线程,都只是一个任务而已,真实干活的是cpu,cpu来做这些任务,而一个cpu同一时刻只能执行一个任务

  并行:同时运行,只有具备多个cpu才能实现并行。

  并发:是伪并行,即看起来是同时运行。单个cpu+多道技术就可以实现并发(并行也属于并发)

  所有现代计算机经常会在同一时间做很多件事,一个用户的pc(无论是单cpu还是多cpu),都可以同时运行多个任务(一个任务可以理解为一个进程)。所有的这些进程都需要被管理,于是一个支持多进程的多道程序系统是至关重要的。

  多道技术:内存中同时存入多道(多个)程序,cpu从一个进程快速切换到另一个,使每个进程各自运行几十或几百毫秒,这样,虽然在某一个瞬间,一个cpu只能执行一个任务,但在1秒内,cpu却可以运行多个进程,这就给人产生类并行的错觉,即伪并发,以此来区分多处理器操作系统的真正硬件并行(多个cpu共享同一个物理内存)

4、同步与异步

  同步:指一个进程在执行某个请求的时候,若该请求一段时间才能返回信息,那么这个进程将会一直等待下去,知道收回信息才继续执行下去。

  异步:指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。

  举个例子,打电话时就是同步通信,发短信时就是异步通信,还有就是数据库的主从复制也是异步操作。

5、进程的创建

  但凡是硬件,都需要有操作系统去管理,只要有操作系统,就有进程的概念,就需要有创建进程的方式,一些操作系统只为一个应用程序设计,比如微波炉中的控制器,一旦启动微波炉,所有的进程都已经存在。

  而对于通用系统(跑很多应用程序),需要有系统运行过程中创建或撤销进程的能力,主要分为4种形式创建新的进程。

  ①系统初始化(查看进程Linux中用ps命令,Windows中用任务管理器,前台进程负责与用户交互,后台运行的进程与用户无关,运行在后台并且只在需要时才唤醒的进程,称为守护进程,如电子邮件、web页面、新闻、打印)

  ②一个进程在运行过程中开启类子进程(如nginx开启多进程,os.fork,subprocess.Popen等)

  ③用户的交互式请求,而创建一个新进程(如用户双击暴风影音)

  ④一个批处理作业的初始化(只在大型机的批处理系统中应用)

  无论是哪一种,新进程的创建都是由一个已经存在的进程执行了一个用于创建进程的系统调用而创建的:

  ①在Unix中该系统调用是:fork,fork会创建一个与父进程一模一样的副本,二者有相同的存储映像、同样的环境字符串和同样的打开文件(在shell解释器进程中,执行一个命令就会创建一个子进程)

  ②在Windows中该系统调用是:CreateProcess,CreateProcess既处理进程的创建,也负责把正确的程序装入新进程。

  关于创建的子进程,Unix和Windows

  1、相同的是:进程创建后,父进程和子进程有各自不同的地址空间(多道技术要求物理层面实现进程之间内存的隔离),任何一个进程在其地址空间中的修改都不会影响到另外一个进程。

  2、不同的是:在Unix系统中,子进程的初始地址空间是父进程的一个副本,提示:子进程和父进程是可以有只读的共享内存区的。但是对于Windows系统来说,从一开始父进程与子进程的地址空间就是不同的。

6、进程的终止:

  ①正常退出(自愿,如用户点击交互式页面的叉号,或程序执行完毕调用发起系统调用正常退出,在Linux中用exit,在Windows中用ExitProcess)

  ②出错退出(自愿,如执行python a.py时a.py不存在)

   ③严重错误(非自愿,执行非法指令,如引用不存在的内存,I/O等,可以捕捉异常,try....except....)

  ④被其它进程杀死(非自愿,如kill -9)

7、进程的层次结构

  无论Unix还是Windows,进程只有一个父进程,不同的是:

  ①在Unix中所有的进程,都是以init进程为根,组成树形结构。父子进程共同组成一个进程组,这样,当从键盘发出一个信号时,该信号被送给当前与键盘相关的进程组中的所有成员。

  ②在Windows中,没有进程层次的概念,所有的进程都是地位相同的,唯一类似于进程层次的暗示,是在创建进程时,父进程得到一个特别的令牌(称为句柄),该句柄可以用来控制子进程,但是父进程有权把该句柄传给其他子进程,这样就没有层次类。

8、进程的状态

  tail -f access.log | grep '404

  执行程序tail,开启类一个子进程,执行程序grep,开启另外一个子进程,两个进程之间基于管道“|”通讯,将tail的结果作为grep的输入。

  进程grep在等待输入(即I/O)时的状态称为阻塞,此时grep命令都无法运行

  其实在两种情况下回导致一个进程在逻辑上不能运行,

  ①进程挂起是自身原因,遇到I/O阻塞,便要让出cpu让其他进程去执行,这样保证cpu一直在工作

  ②与进程无关,是操作系统层面,可能会因为一个进程占用时间过多,或者优先级等原因,而调用其他的进程去使用cpu。

  

9、进程并发的实现

  进程并发的实现在于,硬件中断一个正在运行的进程,把此时进程运行的所有状态保存下来,为此,操作系统维护一张表格,即进程表(process table),每个进程占用一个进程表项(这些表项也称为进程控制块)

  该表存放类进程状态的重要信息:程序计数器、堆栈指针、内存分配状况、所有打开文件的状态、账号和调度信息,以及其他在进程由运行态转为就绪态或阻塞态时,必须保存的信息,从而保证该进程在再次启动时,就像从未被中断过一样。

三、线程

 1、什么是线程:在传统的操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程。

  多线程(即多个控制线程)的概念是,在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间

  进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。即进程只是一个抽象的概念,涉及到具体的干某件事情却是要线程操作的,而该进程下的所有线程是共享该进程所有的资源的。如北京地铁和上海地铁都是不同的进程,都是一个地铁的抽象,而具体的载人则需要具体到13号线等具体的线路。

  

 2、为何要用多线程:多线程指的是,在一个进程中开启多个线程,简单的讲:如果多个任务公用一块地址空间,那么必须在一个进程内开启多个线程。详细的讲分为4点:

    ①多线程共享一个进程的地址空间

    ②线程比进程更轻量级,线程比进程更容易创建可撤销,在许多操作系统中,创建一个线程比创建一个进程要快10-100倍,在有大量线程需要动态和快速修改时,这一特性很有用。

    ③对于计算cpu密集型应用,多线程并不能提升性能,但对于I/O密集型应用,使用多线程会明显地提升速度(I/O密集型根本用不上多核优势)

    ④在多cpu系统中,为了最大限度的利用多核,可以开启多个线程(比开进程开销要小的多)

3、多线程应用举例:开启一个字处理软件进程,该进程肯定需要办不止一件事情,比如监听键盘输入,处理文字,定时自动将文字保存到硬盘,这三个任务操作的都是同一块数据,因而不能用多进程。只能在一个进程里并发地开启三个线程,如果是单线程,那就只能是:键盘输入时,不能处理文字和自动保存,自动保存时又不能输入和处理文字。

4、进程与线程的区别:

  ①Threads share the address space of the process that created it; processes have their own address space线程共享创建它的进程的地址空间,进程有自己的地址空间。

  ②Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process线程可以直接访问其进程的数据段,进程有自己的父进程数据段的副本

  ③Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes线程可以直接与进程的其它线程通信;进程必须使用进程间通信来与兄弟进程通信。

  ④New threads are easily created; new processes require duplication of the parent process新线程很容易创建,新进程需要复制父进程

  ⑤Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes线程可以对同一进程的线程进行相当大的控制;进程只能对子进程执行控制

  ⑥Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes对主线程的更改(取消、优先级更改等)可能会影响流程的其它线程的行为;对父进程的更改不会影响子进程。

5、经典的线程模型

  

原文地址:https://www.cnblogs.com/wangkc/p/7086169.html