zoukankan      html  css  js  c++  java
  • 进程和线程的对比和区别(转)

    一、什么是进程,什么是线程?

    1.1 进程

    • 进程中包括有多个线程,进程与进程之间是相对比较独立的。
    • 进程中有一个逻辑内存,每个进程都会有分配到一个独立的内存空间,还分配了一个文件/网络句柄,
    • 句柄类似一个标识符,所有的进程所或多或少都有一定的句柄数的引用,句柄实际上是一个指针,指向一块包含具体信息数据的内存,所以句柄是当你要访问该进程时取得的,使用完必须释放。(打个比方,我要使用redis需要打开6379端口,这个时候需要访问句柄,获取到内存地址去访问获取对应的资源来执行该进程)
    • 一个进程可以拥有多个句柄数目,但是只有一个进程ID
    • 进程不同时刻所引用的句柄数目是不一定的

    • 为了描述控制进程的运行,系统中存放进程的管理和控制信息的数据结构称为进程控制块(PCB Process Control Block),它是进程实体的一部分,是操作系统中最重要的记录性数据结构(还没查到它存在哪里,待补充)

                                                               进程结构

    1.2 线程

    • 线程中有一个栈内存(很多人把它称为堆栈),主要用来存储局部变量资源或者内存地址
    • 还有一个PC块,主要是存储下一条执行指令的地址,PC是指向一块共同的内存(进程里面的被系统分配到的逻辑内存)。
    • TCS :ThreadLocalStorage 主要存储线程自己定义的变量,不想和其他线程进行共享,理解为线程的私有变量。
    • 线程共享进程的资源主要有:进程代码块、进程的全局和静态变量、进程打开的文件描述符、信号的处理器、进程当前的目录、进程ID、进程组ID

    二、进程和线程的区别

    • 进程是程序资源分配的最小单位,线程是程序执行的最小单位(因为进程有个独立的地址空间;线程在执行中是不能再拆解的)。
    • 进程有自己的内存地址空间,线程包含在进程的地址空间中。
    • 相对于进程与进程之间线程之间通信方式比较方便,线程能共享进程分配到的逻辑内存的资源。也就是说,同一进程下的线程共享全局变量、静态变量等数据,具体共享的内容1.2中介绍线程已经说明。
    • 进程的分配开销比线程大,但是进程的健壮性比线程高,因为进程间不会互相影响,线程一个挂掉了可能会造成进程崩溃。
    • 也可以这么说,线程是程序执行的单位,进程只是存放线程的容器,容器会提供线程执行的资源。

    三、进程和进程之间的通信方式

    因为进程与进程之间是相互独立的,所以关于进程之间的通信数据共享复杂,需要用IPC;数据是分开的,同步简单,但是占用内存多,切换复杂,CPU利用率低。(因为切换过程中cpu是闲置的)

    IPC的方式通常有:管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等

    3.1 管道

    管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。

    3.1.1 管道的特点

    • 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。
    • 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
    • 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中

    3.1.2 原型结构

    当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。如下图:要关闭管道只需将这两个文件描述符关闭即可。

     
    管道原型

    3.13 示例

    单个进程中的管道几乎没有任何用处。所以,通常调用 pipe 的进程接着调用 fork,这样就创建了父进程与子进程之间的 IPC 通道。如下图所示:

     
    示例

    若要数据流从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,则可以使数据流从子进程流向父进程。

    3.2 有名管道FIFO

    FIFO,也称为命名管道,它是一种文件类型。

    3.2.1 特点

    • 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
    • FIFO可以在无关的进程之间交换数据,与无名管道不同。
    • FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中

    3.2.2 介绍

    FIFO的通信方式类似于在进程中使用文件来传输数据,只不过FIFO类型文件同时具有管道的特性。在数据读出时,FIFO管道中同时清除数据,并且“先进先出”。

    3.3 消息队列

    消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。用户进程可以向消息队列添加消息,也可以向消息队列读取消息。

    3.3.1 特点

    • 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级
    • 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除,所以另一个进程读写的时候要判断前进程是否已经读完数据。
    • 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的指定类型读取

    3.4 信号量

    信号量(semaphore)与已经介绍过的 IPC 结构不同,它是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。

    3.4.1 特点

    • 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存
    • 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作
    • 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数
    • 支持信号量组。

    3.5 共享内存

    共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区。

    3.5.1 特点

    • 共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。
    • 因为多个进程可以同时操作,所以需要进行同步
    • 信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。

    3.6 五种通信方式的对比

    1.管道:速度慢,容量有限,只有父子进程能通讯
    2.FIFO:任何进程间都能通讯,但速度慢
    3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题
    4.信号量:不能传递复杂消息,只能用来同步
    5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存(之前见到项目中多线程用共享内存是为啥呢?)

    四、线程与线程之间的通信(多线程)

    4.1 同步

    4.2 wait和notify/notifyAll机制

    4.3 while轮询的方式

    4.4 管道通信

    4.5 Semaphore 信号量



    作者:浅蓝色的麻吉
    链接:https://www.jianshu.com/p/00bd894ff86c
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    新战场:https://blog.csdn.net/Stephen___Qin
  • 相关阅读:
    [代码质量] Git统计本次提交新增代码行数,建议每个评审commit新增行数小于400行
    [Web 安全] WASC 和 OWASP两个web安全方面组织机构介绍
    [web 前端] Npm package.json与package-lock.json文件的作用
    Mac IDEA 插件 lombok
    IDEA 导入新的项目步骤
    IDEA for Mac 快捷键
    Flink --- hello world
    LogisticRegression回归算法 Sklearn 参数详解
    keep going
    在 macOS 上快速新建 txt 文本文件
  • 原文地址:https://www.cnblogs.com/Stephen-Qin/p/11853786.html
Copyright © 2011-2022 走看看