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

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

    1.1 进程

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


       
      进程结构

    1.2 线程

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

    二、进程和线程的区别

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

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

    因为进程与进程之间是相互独立的,所以关于进程之间的通信数据共享复杂,需要用IPC;数据是分开的,同步简单,但是占用内存多,切换复杂,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
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    【转】【SEE】基于SSE指令集的程序设计简介
    【转】【Asp.Net】asp.net服务器控件创建
    ControlTemplate in WPF ——ScrollBar
    ControlTemplate in WPF —— Menu
    ControlTemplate in WPF —— Expander
    ControlTemplate in WPF —— TreeView
    ControlTemplate in WPF —— ListBox
    ControlTemplate in WPF —— ComboBox
    ControlTemplate in WPF —— TextBox
    ControlTemplate in WPF —— RadioButton
  • 原文地址:https://www.cnblogs.com/sandea/p/11777416.html
Copyright © 2011-2022 走看看