1.1 进程产生的背景

最初的计算机只能接受一些特定的指令,用户每输入一个指令,计算机就做出一个操作。当用户在思考或者输入时,计算机就在等待。这样效率非常低下,在很多时候,计算机都处在等待状态。

批处理操作系统

后来有了批处理操作系统,把一系列需要操作的指令写下来,形成一个清单,一次性交给计算机。用户将多个需要执行的程序写在磁带上,然后交由计算机去读取并逐个执行这些程序,并将输出结果写在另一个磁带上。

批处理操作系统在一定程度上提高了计算机的效率,但是由于批处理操作系统的指令运行方式仍然是串行的,内存中始终只有一个程序在运行,后面的程序需要等待前面的程序执行完成后才能开始执行,而前面的程序有时会由于I/O操作、网络等原因阻塞,所以批处理操作效率也不高

进程的提出

人们对于计算机的性能要求越来越高,现有的批处理操作系统并不能满足人们的需求,而批处理操作系统的瓶颈在于内存中只存在一个程序,那么内存中能不能存在多个程序呢?这是人们亟待解决的问题。

于是,科学家们提出了进程的概念。

进程就是应用程序在内存中分配的空间,也就是正在运行的程序,各个进程之间互不干扰。同时进程保存着程序每一个时刻运行的状态。

程序:用某种编程语言(java、python等)编写,能够完成一定任务或者功能的代码集合,是指令和数据的有序集合,是一段静态代码

此时,CPU采用时间片轮转的方式运行进程:CPU为每个进程分配一个时间段,称作它的时间片。如果在时间片结束时进程还在运行,则暂停这个进程的运行,并且CPU分配给另一个进程(这个过程叫做上下文切换)。如果进程在时间片结束前阻塞或结束,则CPU立即进行切换,不用等待时间片用完。

当进程暂停时,它会保存当前进程的状态(进程标识,进程使用的资源等),在下一次切换回来时根据之前保存的状态进行恢复,接着继续执行。

使用进程+CPU时间片轮转方式的操作系统,在宏观上看起来同一时间段执行多个任务,换句话说,进程让操作系统的并发成为了可能。虽然并发从宏观上看有多个任务在执行,但在事实上,对于单核CPU来说,任意具体时刻都只有一个任务在占用CPU资源。

对操作系统的要求进一步提高

虽然进程的出现,使得操作系统的性能大大提升,但是随着时间的推移,人们并不满足一个进程在一段时间只能做一件事情,如果一个进程有多个子任务时,只能逐个得执行这些子任务,很影响效率。

比如杀毒软件在检测用户电脑时,如果在某一项检测中卡住了,那么后面的检测项也会受到影响。或者说当你使用杀毒软件中的扫描病毒功能时,在扫描病毒结束之前,无法使用杀毒软件中清理垃圾的功能,这显然无法满足人们的要求。

线程的提出

那么能不能让这些子任务同时执行呢?于是人们又提出了线程的概念,让一个线程执行一个子任务,这样一个进程就包含了多个线程,每个线程负责一个单独的子任务。

使用线程之后,事情就变得简单多了。当用户使用扫描病毒功能时,就让扫描病毒这个线程去执行。同时,如果用户又使用清理垃圾功能,那么可以先暂停扫描病毒线程,先响应用户的清理垃圾的操作,让清理垃圾这个线程去执行。响应完后再切换回来,接着执行扫描病毒线程。

注意:操作系统是如何分配时间片给每一个线程的,涉及到线程的调度策略,有兴趣的同学可以看一下《操作系统》,本文不做深入详解。

总之,进程和线程的提出极大的提高了操作系统的性能。进程让操作系统的并发性成为了可能,而线程让进程的内部并发成为了可能。

多进程的方式也可以实现并发,为什么我们要使用多线程?

多进程方式确实可以实现并发,但使用多线程,有以下几个好处:

  • 进程间的通信比较复杂,而线程间的通信比较简单,通常情况下,我们需要使用共享资源,这些资源在线程间的通信比较容易。
  • 进程是重量级的,而线程是轻量级的,故多线程方式的系统开销更小。

进程和线程的区别

进程是一个独立的运行环境,而线程是在进程中执行的一个任务。他们两个本质的区别是是否单独占有内存地址空间及其它系统资源(比如I/O)

  • 进程单独占有一定的内存地址空间,所以进程间存在内存隔离,数据是分开的,数据共享复杂但是同步简单,各个进程之间互不干扰;而线程共享所属进程占有的内存地址空间和资源,数据共享简单,但是同步复杂。

  • 进程单独占有一定的内存地址空间,一个进程出现问题不会影响其他进程,不影响主程序的稳定性,可靠性高;一个线程崩溃可能影响整个程序的稳定性,可靠性较低。

  • 进程单独占有一定的内存地址空间,进程的创建和销毁不仅需要保存寄存器和栈信息,还需要资源的分配回收以及页调度,开销较大;线程只需要保存寄存器和栈信息,开销较小。

另外一个重要区别是,进程是操作系统进行资源分配的基本单位,而线程是操作系统进行调度的基本单位,即CPU分配时间的单位 。

1.2 上下文切换

上下文切换(有时也称做进程切换或任务切换)是指 CPU 从一个进程(或线程)切换到另一个进程(或线程)。上下文是指某一时间点 CPU 寄存器和程序计数器的内容。

寄存器是cpu内部的少量的速度很快的闪存,通常存储和访问计算过程的中间值提高计算机程序的运行速度。

程序计数器是一个专用的寄存器,用于表明指令序列中 CPU 正在执行的位置,存的值为正在执行的指令的位置或者下一个将要被执行的指令的位置,具体实现依赖于特定的系统。

举例说明 线程A - B

1.先挂起线程A,将其在cpu中的状态保存在内存中。

2.在内存中检索下一个线程B的上下文并将其在 CPU 的寄存器中恢复,执行B线程。

3.当B执行完,根据程序计数器中指向的位置恢复线程A。

CPU通过为每个线程分配CPU时间片来实现多线程机制。CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。

但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。

上下文切换通常是计算密集型的,意味着此操作会消耗大量的 CPU 时间,故线程也不是越多越好。如何减少系统中上下文切换次数,是提升多线程性能的一个重点课题。


参考资料

  • 线程的几种状态转换
  • 进程和线程的由来与别
  • 进程、线程、多线程相关总结
  • 进程的概念/标识/结构/状态
  • 操作系统 - 进程的概念
  • 进程管理笔记一、进程的概念及其产生的背景
  • 上下文切换
  • 进程的概念/标识/结构/状态
  • 线程的生命周期及状态转换详解
  • 进程与线程

进程与线程的基本概念相关推荐

  1. java进程与线程_Java多线程笔记(零):进程、线程与通用概念

    前言 不积跬步,无以至千里:不积小流,无以成江海.在学习Java多线程相关的知识前,我们首先需要去了解一点操作系统的进程.线程以及相关的基础概念. 进程 通常,我们把一个程序的执行称为一个进程.反过来 ...

  2. Java多线程笔记(零):进程、线程与通用概念

    前言 不积跬步,无以至千里:不积小流,无以成江海.在学习Java多线程相关的知识前,我们首先需要去了解一点操作系统的进程.线程以及相关的基础概念. 进程 通常,我们把一个程序的执行称为一个进程.反过来 ...

  3. 进程和线程的基本概念

    进-线目录 前言 1.为什么会产生进程? 2.进程是什么? 3.为什么会产生线程? 4.多进程可以实现并发,为什么还要使用线程? 5.进程和线程的区别 6.理解上下文切换 前言 程序:指令和数据的集合 ...

  4. 第一章 进程与线程的基本概念

    1.1 进程产生的背景 最初的计算机只能接受一些特定的指令,用户每输入一个指令,计算机就做出一个操作.当用户在思考或者输入时,计算机就在等待.这样效率非常低下,在很多时候,计算机都处在等待状态. 批处 ...

  5. 程序、进程、线程汇总(概念篇)

    引入 众所周知,程序.进程和线程这三个概念相辅相成,据说也是面试的一大热点,既然如此,笔记中就应该有它们三个的身影. 定义 一.程序 程序是存放在存储介质上的一个可执行文件. 二.进程 进程是程序的执 ...

  6. 第一节 并发基础概念及实现、进程、线程基本概念

    1.并发.进程.线程的基本概念和综述 并发.线程.进程要求必须掌握!!!! 1.1 并发 概念:两个或更多的任务(独立的活动)同时发生(进行):一个程序同时执行多个独立的任务: 以往的计算机通常是单核 ...

  7. 进程和线程的概念、区别和联系

    进程(process)和线程(thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握. 最近,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂. 进程与线程的一个简单解释 在这 ...

  8. 并发和多线程(一)并发、进程、线程概念

    一.并发.进程.线程的基本概念和综述 1.1 并发 两个或者更多的任务(独立的活动)同时发生(进行):一个程序同时执行多个独立的任务: 以往计算机,单核cpu(中央处理器):某一个时刻只能执行一个任务 ...

  9. C++11多线程第一篇:并发基本概念及实现,进程、线程基本概念

    文章目录 1.并发基本概念及实现,进程.线程基本概念 1.1 并发.进程.线程的基本概念和综述 1.1.1 并发.并行 1.1.2 可执行程序 1.1.3 进程 1.1.4 线程 1.1.5 程序.进 ...

最新文章

  1. hibernate 基础学习
  2. spring boot原理_SpringBoot-02-原理初探之主启动类
  3. gdb / 调试进入 so 库的方法
  4. handler和thread之间如何传输数据_网线虽常见,学问可不少,科普一下网线的简单知识及如何选择网线...
  5. strcpy、strncpy与memcpy的区别与使用方法
  6. loadedapk.java_android,_java.lang.ClassCastException: android.os.BinderProxy,android - phpStudy
  7. Spark SQL兼容Hive及扩展
  8. 新浪的动态策略灰度发布系统:ABTestingGateway
  9. sourceTree对git的新建项目、储藏代码、切换分支、回滚代码、提交代码
  10. 一起谈.NET技术,Linq学习笔记
  11. 【对讲机的那点事】无线电对讲系统在隧道中的应用
  12. 分布式服务防雪崩熔断器(Hystrix),实现服务降级
  13. SP2010开发和VS2010专家食谱--第七章节--使用客户端对象模型
  14. Java常用算法-二分查找算法(两种方法实现)
  15. 从图书馆进入网络刷题练习与考试平台
  16. 基于OpenCV 人工神经网络的喷码字符识别(C++)
  17. 将keras的模型封装成可转换为tensorlow的.pb格式,并生成.pbtxt文件
  18. STM32RTC唤醒功能配置(基于LL库)
  19. Mysql的一揽子方案用法
  20. 让linux脚本输出声音,即使在linux中没有麦克风,声音输出也会出现在声音输入中...

热门文章

  1. iqooneo5支持nfc功能吗
  2. Java获取当前日期的前一天
  3. proguard java 教程,ProGuard 初探,新手入门必知必会
  4. 计算机英语课学期总结
  5. 3天线下K8s封闭式实战培训
  6. handbrake 下载是php,Handbrake 优秀开源视频转换软件
  7. 一起学习正则表达式(四)常见的4种匹配模式
  8. 终于有人说清楚 “幸存者偏差” 了
  9. python中argv的使用_python中使用sys.argv命令行参数
  10. 基于springboot+vue的ERP系统