在某次面试中,面试官问我,能具体讲下线程与进程吗?我:关于线程,JS其实就是一门单线程语言,意味着他只能在同一时间只能处理一件事。而Java是多线程的,可以同时处理执行任务。面试官追问:可以抛开JS这门语言聊聊线程与进程吗?我:….。 后来面试结束后,回想到这个问题,觉得回答的非常糟糕。第一点是因为对于他的提问,我的回答偏离了问题的核心。第二点是因为我对这两个概念没有了解。所以为了搞懂这两个概念,私下里我通过在网上查询资料,然后根据自己的理解总结下线程与进程的含义及区别。

进程

在早期的只有单核CPU的时代,操作系统管理协调者我们的各种硬件与软件。我们使用操作系统一边浏览网页,一边打开音乐软件听音乐。在我们进行这两项进程的过程中,CPU一直帮助我们处理运算着。可是同时处理两个进程,CPU是怎么做到的?答案就是通过时间片轮转调度

轮转的意思是每个进程会被操作系统分配一个时间片,即每次被CPU选中来执行当前进程的时间。当执行当前进程(任务)的时间一过,无论进程是否运行结束,操作系统就会立即将CPU转到另一个进程中去执行。

操作系统为什么会这样做呢?假设没有这种轮转调度机制,首先它不清楚该执行A进程还是B进程。其次无论执行哪种进程,另外的其他进程肯定是不被执行的,程序就像无运行的状态。如果CPU快速的分别执行A进程和B进程,在人的认知当中会觉得这样运行起来很卡..其实CPU的运行速度已经快到让人感觉不到这种不同进程切换的顿挫感。它会处理的就像两个程序“并行运行”一样。

如上图所示,假设每个小方块代表一个时间片,大概是100ms。我们同时执行着三个不同的软件。CPU首先处理Word进程,100ms时间一到CPU就会强制切换到QQ进程,处理100ms后又切换到网易云。如此反复不断的执行切换。如果把以上某个进程单独拿出来看的话,如果时间片足够小,其实在人看来就是像最后一个处理过程。

在windows操作系统中,打开任务管理器可以看到我们目前所有的进程。在CPU那一栏,会动态的更新占用率,占用率数字越大,代表当前时间片正在执行的进程。

线程

当运行的进程越来越多的时候,会发现进程的创建、切换有着较大的时空开销,于是后面出现一种叫 SMP(Symmetrical Multi-Processing)的对称多处理技术,也就是我们俗称的线程。线程的切换开销要比进程小很多,这是因为每个进程都有属于自己的完整虚拟地址,而线程隶属于某一个进程,与进程内的其他线程公用这片地址空间,基本上就可以利用进程所拥有的资源,无需调用其他资源。所以线程的切换调度所用的开销非常小。

如上图所示,我们拿QQ软件来举例,此刻假设没有线程技术的出现,当QQ被CPU“执行”时,这时候CPU首先执行聊天还是处理页面的更新呢?如果只处理聊天消息推送,那么页面就不会更新,看起来像“卡住”了一样。有了线程之后,每次CPU执行100ms,其中30ms用于处理聊天,40ms用于处理文件传输,剩余30ms处理页面刷新。这样就使得QQ的功能像是“并行”运行。

进程与线程的区别

  • 一个进程可以包含多个线程,而线程却无法包含进程
  • 进程与进程之间资源不共享,而线程之间资源可以共享
  • 进程之间不会相互影响,比如当某个进程挂掉了,其他进程可以正常运行。而一个线程挂掉,将会导致整个线程受影响。
  • 进程要比线程消耗更多计算机资源