操作系统、单核CPU运作、CPU时间片、进程、线程、多线程并发、多线程安全问题、多核cpu并行
冯诺依曼计算机模型详解
现代计算机模型是基于-冯诺依曼计算机模型
计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,按指令的要求,从存储器中取出数据进行指定的运算和逻辑操作等加工,然后再按地址把结果送到内存中去。接下来,再取出第二条指令,在控制器的指挥下完成规定操作。依此进行下去。直至遇到停止指令。
程序与数据一样存贮,按程序编排的顺序,一步一步地取出指令,自动地完成指令规定的操作是计算机最基本的工作模型。这一原理最初是由美籍匈牙利数学家冯.诺依曼于1945年提出来的,故称为冯.诺依曼计算机模型。
计算机五大核心组成部分
1. 控制器(Control):是整个计算机的中枢神经,其功能是对程序规定的控制信息进行解释,根据其要求进行控制,调度程序、数据、地址,协调计算机各部分工作及内存与外设的访问等。
2. 运算器(Datapath):运算器的功能是对数据进行各种算术运算和逻辑运算,即对数据进行加工处理。
3. 存储器(Memory):存储器的功能是存储程序、数据和各种信号、命令等信息,并在需要时提供这些信息。
4. 输入(Input system):输入设备是计算机的重要组成部分,输入设备与输出设备合你为外部设备,简称外设,输入设备的作用是将程序、原始数据、文字、字符、控制命令或现场采集的数据等信息输入到计算机。常见的输入设备有键盘、鼠标器、光电输入机、磁带机、磁盘机、光盘机等。
5. 输出(Output system):输出设备与输入设备同样是计算机的重要组成部分,它把外算机的中间结果或最后结果、机内的各种数据符号及文字或各种控制信号等信息输出出来。微机常用的输出设备有显示终端CRT、打印机、激光印字机、绘图仪及磁带、光盘机等。
下图-冯诺依曼计算机模型图
上面的模型是一个理论的抽象简化模型,它的具体应用就是现代计算机当中的硬件结构设计:
进程与线程
进程(Process)具有单独的计算资源,如内存空间。
线程(Thread)是进程的一个子集,一个进程默认启动一个线程,也可以通过多线程编程,启动多个线程,多个线程共享共享进程的资源。
在多核架构出现之前,CPU在某个特定时刻只能执行某个程序,无法并行。就像人在某个时刻只能做一件事情,不可能“吃着火锅还唱着歌”,因为两项活动都要占用嘴。如果要干另一件事,就必须把其中一件事停下来。
单核单线程
CPU处理速度是纳秒级,速度非常快,所以在单核时代,为了同时处理多项任务,cpu会创建一个队列来管理线程,线程是先进先执行,并会为每个线程分配一个执行时间这个也叫时间片如20ms,如果时间片用完了线程还没执行完则会让线程重新回到队列尾端从而执行下一个线程的任务。
如cpu先“吃会火锅”,再“唱会歌”,边吃边唱进行循环模式。
cpu这种在各个线程之间高速切换,以这种形式实现多线程并发功能。
当然单个CPU每次切换不同的线程任务,会产生一些资源开销。吃饭和唱歌之间,总要让人稍微歇歇嘛!
在CPU上快速在多个任务间切换,对于使用者来说,就像并发(Concurrent)地执行了多个任务一样。
在Windows 系统中线程轮转时间片大约是20ms(1 毫秒=1000000 纳秒),如果某个线程所需要的时间小于20ms,那么不到20ms就会切换到其他线程;如果一个线程所需的时间超过20ms,系统也最多只给20ms,除非意外发生(那可能导致整个系统无响应),而Linux/unix中则是5~800ms。
以网页浏览器为例,浏览器打开一个网页时通常需要下载网页中素材同时也要渲染成美观的画面。在单核场景下,时间被切成了不同的片段,某段时间只能用来做渲染、缓存或下载中的一项任务。每个任务都有优先级,CPU优先执行高优先级的任务。比如,浏览器打开一个新网页时,要第一时间把网页展示出来,背景音乐下载比较慢,可以等网站渲染好后再下载,所以有时候背景音乐会比网页晚半分钟。
多核多线程
多核架构提供给用户多个可以独立计算的核心,这也意味着计算机可以同时并行执行多项任务,即并行计算(Parallel Computing)。那么一个网页浏览器使用一个核渲染网页,另一个核缓存其他素材,第三个核下载背景音乐。
使用htop查看CPU和内存利用率
上图是我的macOS性能监控的一个软件(htop),Windows上类似的软件是任务管理器。图片绿色横条上方展示了当前8个CPU核的及内存利用率,绿色横条下方是我启动的多个进程,其中标蓝色的是我的Chrome浏览器的进程,我还启动了Photoshop等软件。
当多个核心都处理相同任务,极有可能使用同一块数据,就有可能出现数据读写的问题。
线程安全问题
例如,进行i = i + 1操作,如果两个线程短时间内都对变量i加一,变量应该被加了两次。由于两个线程相隔时间太短,加上前面所说的缓存机制,计算的过程和临时结果还在寄存器和L1缓存,没来得及写到主存上。线程B读到还是较老的数据,这样就出现了数据不一致的情况。这种问题被称为线程安全问题。一般需要使用锁(乐观锁CAS、悲观锁AQS)来处理线程安全问题,这些在后面会深入去作详细的了解,这章节只是先了解一下操作系统的一些基础知识、CPU运作、进程、线程、多线程并发、多线程安全问题、多核cpu并行这些概念。