go语言体系课视频配套文档

Chatok.cn go语言聊天
Chatok.cn go语言聊天
文章作者: 全栈编程@luboke.com
版权声明: 本文章为全栈编程go语言体系课视频教程配套电子书,版权归 全栈编程@luboke.com所有,欢迎免费学习,转载必须注明出处!但禁止任何商业用途,否则将受到法律制裁!

进程与程序

程序是什么?进程又是什么?程序和进程之间有何种关系呢? 

进程是操作系统为了执行我们所编写的程序而启动的服务

程序就是我们编写的代码文件,程序中规定了要做的事情,完成的功能等等由相应的指令与数据构成的源代码文件,存储在计算机的硬盘当中。

只有当我们编写的程序运行在操作系统上,由操作系统启动进程服务,操作系统负责将程序源代码从硬盘加载到内存中来执行。

我们平时使用的微信,qq,浏览器等等在运行起来之后就是进程;操作系统会为这些应用程序启动一个进程。这个进程如果要运行起来还要包含应用程序在运行中需要用到和管理的各种资源。

这些资源包括但不限于内存地址空间、文件和设备的句柄以及线程。而这里的线程被称为是一个执行空间,这个空间会被操作系统调度来运行函数中所写的代码。每个进程至少包含一个线程,每个进程的初始线程被称作主线程。因为执行这个线程的空间是应用程序的本身的空间,所以当主线程终止时,应用程序也会终止。

操作系统将线程调度到某个处理器上运行,这个处理器并不一定是进程所在的处理器。不同操作系统使用的线程调度算法一般都不一样,但是这种不同会被操作系统屏蔽,并不会展示给程序员。

是一个运行在自己内存地址空间里的独立执行体。一个进程由一个或多个操作系统线程组成,这些线程其实是共享同一个内存地址空间的一起工作的执行体。在实际的工作当中编写的程序基本上都是多线程的,多线程的程序可以让用户或计算机不必等待,这样可以同时服务多个请求(如 Web 服务器),或增加性能和吞吐量(例如,通过对不同的数据集并行执行代码)。

并发

像在早期的单核处理器当中并行运行多个进程,也就是几时运行多个程序,比如同时聊qq,聊微信,看电影,听歌等等吧,这里的并行运行并不是真正的并发,从计算机执行的角度来说是并发运行。

并行(parallelism),指的是在某一时间点同时,并列的意思。即在那一时刻能够同时执行多个进程的能力。单核心CPU在某一时刻只能执行一个进程,如果需要并行的执行多个进程,必须要使用多核CPU才能达到真正的并行。 

并发(concurrency)

并发的意思是说能够同时处理多个请求任务。这里的同时指的是在某个时间点上,当有多个请求任务到达时,都要被处理完。有可能是一个一个的执行,也有可能是我们编写的多线程同时的执行,以使任务完成。

并发:以当前web服务器所接收的客户端请求为例

提到并发,在实际应用中我们以并发数的来衡量,它表示有多少个待处理的任务,从某个时间点或一个规定的时间段去看,有多少个同时存在的任务需要被处理,这个数量就是那一时间点或那个时间段的并发数,所以并发任务是有到达的先后顺序的。比如上图中N多个不同的用户向web服务器发起访问index.html的请求,假如在一秒内有1000个并发请求是需要我们的服务器来处理的。

既然涉及到并发请求,那么也就涉及到对并发请求的响应处理,一般使用处理并发数来衡量,所谓的处理并发数表示在某个时间段内(通常指的是1秒内)同时处理了多少并发请求。处理并发数是衡量cpu或者服务器执行性能或效率的依据。

以我们的服务器为例,其中就是一台计算机,在操作系统上要同时运行多个程序,比如N多个用户的请求index.html,所有的进程都在等待被调度,这就是并发。

假如我们的服务器是单核CPU,那么就只能按顺序执行。

如果有双核CPU,那么可以让CPU1执行其中的2个请求【2个进程】,CPU2执行另外3个请求【3个进程】,两个CPU同时都处于工作状态。如图,5个网络请求被2个CPU同时处理,以提高执行效率与响应,提高用户体验。

 

假设有个程序中编写了多进程(假如两个进程)的代码,但是只有单核CPU,那么这两个进程只能以伪并行的方式执行,正如执行一会进程A,再执行一会进程B。这其实比串行的单进程代码效率更低,因为进程切换有开销。但如果有多核CPU,那么这两个进程可以同时被两个CPU拿去执行,这才是真正的并行,效率才会更高。

关于并发和并行,需要理解的东西概括起来就两句话:

并发和并行完全是两个概念。并发描述的是有多个任务等待着要被处理这件事,并行描述的是能同时一次性处理多个任务的能力。
只有多核CPU才能实现真正的并行,才具有真正的高效率,单核CPU处理多进程通过进程切换实现,是伪并行,效率反而会比串行方式更低,因为进程切换会消耗资源和时间。

分时系统与上下文切换

现代操作系统都支持多任务同时执行。比如可以同时看网页、发邮件、聊QQ、听音乐等。要想实现真正的并行运行多个进程,只能使用多核CPU来实现。所以操作系统提供的多程序同时运行是个假象。

这种假象在计算机当中有个专业术语,被称为 分时系统 ,就是说让CPU执行一会进程A,然后停下来去执行一会进程B,再停下来执行一会进程A。这样每个进程都只执行了一会,然后切换到另一个进程去执行。每一段执行和切换的时间很短(每秒能执行很多个进程),使得用户以为进程根本未停过,从而形成了假象。

以下描述了分时系统的进程切换方式。进程A执行一会后切换到进程B,B执行一会后又切换到C,C执行一会后又切换到B,再切换回A

 

进程在执行的过程中不断切换,这里就是CPU从一个进程切换到另一个进程,切换的过程涉及到了一个专业的术语被称为上下文切换(context switch)上下文切换可以直接理解为进程的切换,之所以使用上下文这个术语,是因为CPU要从进程A切换到进程B时,必然要保存进程A的执行环境,比如进入切换时进程A执行到了哪个地方,以便下次切换回进程A的时候能够从这里恢复继续执行,此外,既然要切换到进程B,必然还要恢复之前已保存好的进程B的执行环境,才能知道从哪里开始继续执行进程B。而在计算机世界中,环境上下文通常是可以互换的概念,所以CPU的上下文切换正是两个前后进程执行环境的切换

上下文切换是操作系统同时运行多个程序的基本保证,它表现为:运行一会进程A,再运行一会进程B。

在上下文切换时,有一些必要的事情要做。例如,CPU要从进程A切换到进程B时,必然要保存好进程A上下文,以便下次切换回进程A的时候能够原样恢复继续运行。另一方面,既然要切换到进程B,必然还要恢复之前已保存好的进程B的上下文,才能原样恢复进程B并继续执行进程B。很多时候,保存上下文被称为”保护现场”,恢复上下文被称为”恢复现场”。

每个进程执行一会再切换到另一个进行,这里的执行时长被称为时间片

每一个进程都有自己的执行时间片,当时间片耗尽,cpu必须切换到其它进程,这里就涉及到每一个进程的执行时间问题,即每一个进程执行的时间片分配多少合适的问题。

我们来分析一下:

假如为每个进程分配的时间片过短,这会导致cpu的上下文切换过于频繁,而cpu的上下文功换是有时间开销的,时间片过长;

假如时间片过长,那么每个进程需要等待运行的时间就越长,意味着交互性越差。

所以进程执行合理的时间片应该是由cpu动态计算。

分时系统的设计可以大大提高用户体验,提高交互性,这样每个进程都可以尽快地执行起来,都能够更快地被响应。

另一个问题,每个进程从开始启动到完成执行,由于每件进程执行的任务的复杂度不同,肯定的复杂度越高,则需要花费更长时间,而且很多时间处于等待状态。

另外既然cpu要不断的切换进程,操作系统如何选择下一个要执行的进程?

选择下一个要执行的进程,是操作系统的进程调度程序(也称为调度器或调度类)来决定的,调度器根据一些调度算法策略决定哪个进程将被调度到,作为下一个要执行的进程。

进程调度算法策略的两个关键性指标正是响应时间和周转时间。

响应时间体现的是交互性和公平性,响应时间越短,表示交互时能更快得到响应,比如当敲下键盘时,用户肯定不希望还要等一段时间才显示字符。周转时间体现的是何时完成任务的问题,

周转时间越短,表示从启动开始到执行结束所花的时间更短,也就是更快完成任务。

分时系统可以保证为每个进程分配固定的时间片能保证每个进程都有机会执行,但总会有一些进程是比较重要的,它们的优先级比较高,当它们有任务需要优先执行时,就可以从当前正在执行的进程处去抢占CPU执行时间片,在计算机中被称为抢占式多任务处理。 

文章作者: 全栈编程@luboke.com
版权声明: 本文章为全栈编程go语言体系课视频教程配套电子书,版权归 全栈编程@luboke.com所有,欢迎免费学习,转载必须注明出处!但禁止任何商业用途,否则将受到法律制裁!
copyright © 2020 全栈编程@luboke.com