专栏首页用户6811391的专栏全方位理解进程和线程

全方位理解进程和线程

1 进程和线程形象解释

首先,阮一峰《进程与线程的一个简单解释》一文中形象生动地将计算机 CPU 比做一个工厂,进程相当于工厂内不同车间,线程相当于车间内不同协作的工人。

工厂电力有限,一次只能一个车间开工:单个CPU一次只能运行一个进程,其他进程处于非运行状态。

一个车间里可以有很多工人协同工作:一个进程可以包括多个线程协同进行。

车间空间由工人们共享:一个进程的内存空间是每个线程共享的。

车间内每间房间的大小不同,里面人满的时候,其他人就不能进去了:某些线程使用某些共享内存时,若线程数目超出限制,则其他线程必须等其中线程结束,才能使用这一块内存。

为了控制房间不超出人数限制,就在门口挂一定数量的钥匙,进去的人取一把,出来时放回原处,后到的人若取不到钥匙就在门口排队:该做法叫做“信号量”(Semaphore),用来保证多个线程不会互相冲突,即控制多个线程同时读写某一块内存区域。

操作系统的设计可以归纳为三点:

  1. 以多进程形式,允许多个任务同时运行;
  2. 以多线程形式,允许单个任务分成不同的部分运行;
  3. 提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程和线程之间共享资源。

2 进程和线程时间维度上的解释

该部分来源于知乎问题“线程和进程的区别是什么?”中作者 zhonyong 的高赞回答。

进程和线程都是一个 CPU 工作时间段的描述,颗粒大小不同。

执行一段程序代码,除了CPU以外所有的就构成了这个程序的执行环境,也就是我们所定义的程序上下文。当这个程序执行完了,或者分配给他的CPU执行时间用完了,那它就要被切换出去,在被切换出去的最后一步工作就是保存程序上下文,因为这个是下次他被 CPU 执行的运行环境,必须保存。

在CPU看来所有的任务都是一个一个的轮流执行的,具体的轮流方法就是:先加载程序A的上下文,然后开始执行A,保存程序A的上下文,调入下一个要执行的程序B的程序上下文,然后开始执行B,保存程序B的上下文。

进程就是包含上下文切换的程序执行时间总和 = CPU加载上下文+CPU执行+CPU保存上下文

进程的颗粒度太大,每次都要有上下的调入,保存,调出。如果我们把进程比喻为一个运行在电脑上的软件,那么一个软件的执行不可能是一条逻辑执行的,必定有多个分支和多个程序段,就好比要实现程序A,实际分成 a,b,c等多个块组合而成。

那么这里具体的执行就可能变成:程序A得到CPU =》CPU加载上下文,开始执行程序A的a小段,然后执行A的b小段,然后再执行A的c小段,最后CPU保存A的上下文。

这里a,b,c的执行是共享了A的上下文,CPU在执行的时候没有进行上下文切换的。这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境的、更为细小的CPU时间段

3 进程和线程在操作系统上的解释

该部分来源于《程序员的自我修养(二):操作系统、进程与线程》一文。

在操作系统中执行的程序,都以进程的方式运行在更低的权限中。事实上,操作系统是以进程为单位去分配空间和执行的。但是,进程和程序有什么不同呢?

我们说程序是一组指令的集合,它静态存储于诸如磁盘之类的存储器里;当一个程序被操作系统执行时,它就会被载入内存空间,并在逻辑上产生一个独立的实例,这就是进程。

这就好像是说,程序是一道菜谱,其中的指令,就是指挥你开火加盐的步骤;进程则是烹饪的过程,操作系统按照指令一丝不苟地烹饪,得到的结果就是我们的菜肴。

随着 CPU 频率增长逐渐停滞,CPU 开始向多核的方向发展。为了让多个 CPU 核心同时为我们工作,并行地执行任务,就需要涉及线程的概念。线程的英文是 Thread,有时也称为轻量级进程 (Lightweight Process),它是操作系统进行任务调度的最小单元。线程存活于进程之中;同一个进程中的线程,共享一个虚拟内存空间,以及其中的资源;线程之间各自持有自己的线程 ID、当前指令的指针(PC)、寄存器集合以及栈。

4 进程和线程理论与表述

该部分来源于知乎问题“线程和进程的区别是什么?”中 宇宙之一粟 的回答。

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

线程是进程的一个实体,是独立运行和独立调度的基本单位(CPU上真正运行的是线程)。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

二者的区别:

  1. 进程是资源分配的基本单位;线程是程序执行的基本单位。
  2. 进程拥有自己的资源空间,每启动一个进程,系统就会为它分配地址空间;而线程与CPU资源分配无关,多个线程共享同一进程内的资源,使用相同的地址空间。
  3. 一个进程可以包含若干个线程。

二者优劣比较:

  1. 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(Inter Process Communication,IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。
  2. 线程的调度与切换比进程快很多,同时创建一个线程的开销也比进程要小很多。
  3. 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

口语表述:

进程的本质::正在执行的一个程序,可以进程比作一个容器或者工厂

  1. 进程与进程之间相对独立
  2. 进程可以包括几个或者上百个线程在运行。
  3. 内存(逻辑内存)包括在进程里面,每个进程的内存都是互相独立的,但从一个更高的层次上看,不同的进程也共享着一个巨大的空间,这个空间就是整个计算机。
  4. 进程共有文件/网络句柄(handle),这样可以打开同一个文件,抢同一个网络端口。

线程的本质:真正运行的是一个一个的线程

线程包含:

  1. 栈(堆栈):主线程的main函数、进行函数调用的参数和返回地址、局部变量等内容都会被压入栈内
  2. PC(Program Couner):程序计数器,PC的指针指向代码所在的内存地址。
  3. TLS(Thread local storage):分配内存,存放变量

通信是人的基本需求,进程与进程之间是相互独立的,也有通信需求。根据这一问题就可以展开内容提问:进程/线程如何通信?

答:进程可以通过管道、套接字、信号交互、共享内存、消息队列等等进行通信;而线程本身就会共享内存,指针指向同一个内容,交互很容易。

一旦有了通信,进程就会产生矛盾。这些矛盾就会体现在如何同步上。在单个CPU下,实际上在任何时刻只能有一个进程处于执行状态。而其他进程则处于非执行状态。我们是如何确定在任意时刻到底由哪个进程执行,哪些不执行呢?(如何进行进程调度?)线程之间的关系是合作关系。既然是合作,那就得有某种约定的规则,否则合作就会出问题。(如何进行线程同步?)

还有内存问题,进程要分配内存,所以开销很大;线程只需要分配栈,分配一个PC(程序计数器)就好,内存开销小。

参考链接

  1. 《进程与线程的一个简单解释》阮一峰 http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
  2. 知乎问题“线程和进程的区别是什么?” zhonyong 回答https://www.zhihu.com/question/25532384/answer/81152571
  3. 《程序员的自我修养(二):操作系统、进程与线程》https://liam.page/2017/01/17/layers-and-operation-system/
  4. 知乎问题“线程和进程的区别是什么?” 宇宙之一粟 回答https://www.zhihu.com/question/25532384/answer/1130818664

本文分享自微信公众号 - TTTEED(TEDxPY),作者:TED

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python 刷题笔记:数组专项练习一

    昨天是刷题的第 25 天,基本保持了每天一两道,同步分享了其中前 35 题的记录。通过二十多天的摸索,慢慢熟悉 LeetCode 平台,为了提高刷题学习效率,我...

    TTTEED
  • Python:修炼写轮眼

    情人节写的那篇,在眼睛里添加女友照片,今天做了下修改。先是把贴图换成了写轮眼图片,再就是将单纯的图片展示改成了opencv调用摄像头,对实时获取的图片进行加工再...

    TTTEED
  • 猜音谜——倒放音频挑战赛

    前两天刷哔哩哔哩,看了两期《小翔哥是世界上最帅的男人》和《笑死人的倒放挑战》视频,视频里他们将语音或者音频倒着播放,特别搞笑。

    TTTEED
  • Python多进程多线程对比

    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中...

    不可言诉的深渊
  • Java 并发编程(一):摩拳擦掌

    我喜欢在写文章(不用纸和笔用电脑了)的时候听音乐(不用 MP3 用电脑了),假如电脑只能做一件事情的话,我就只能在写完文章的时候再听音乐,或者听完音乐的时候再开...

    沉默王二
  • httpd的三种模式比较–转

    老七Linux
  • 阿里2018暑期实习内推面经(Java岗),offer已拿到

    整个三月份通过牛客网和网友分享的经验学到了很多东西,现在反馈一下我的面试经历,希望对同学们有帮助。 个人情况:大三本EE方向渣硕,经过实验室学长内推,于三月底完...

    牛客网
  • Python多线程threading用法

    Python里面经常会用到多线程,即所有的方法在同一时间开始运行,而不是按顺序一个一

    py3study
  • 分布式系统的那些事儿(二) - 线程与进程

    线程和进程在之前的文章有讲过,这里简单再说一下吧。 进程,一个程序可以称为一个进程 线程,一个程序中包含多个线程,线程的集合体可以称之为进程。 同一进程中的不...

    风间影月
  • 快速学习-JUC

    在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自...

    cwl_java

扫码关注云+社区

领取腾讯云代金券