作为一名前端的妹子,为了使自己更上一个台阶,下定决心好好提升自己的技术。先从最基础的概念开始吧~~
线程与进程
概念
-
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. -
线程一个进程内部可能包含了很多顺序执行流,每个顺序执行流就是一个线程。线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源[一块内存空间和一组系统资源]. ···[so 难懂~~]
举个🌰
- [
进程]:我们都知道程序,一个程序是静态的,通常是存放在外存中的。而当程序被调入内存中运行后,就成了进程。顾名思义,进程就是进行中的程序,它是个动态的概念。是系统进行资源分配与调度的基本单位。例如在windows中,每一个打开运行的应用程序或后台程序,比如运行中的QQ、谷歌浏览器、网易云音乐、资源管理器等都是一个进程。 - [
单线程] 一个进程内部可能包含了很多顺序执行流,每个顺序执行流就是一个线程。线程又有单线程与多线程之分。我们用js/c/java写的程序大部分时候都是单线程的编程。将主文件作为程序的入口,依次执行,直到执行完全部代码[ps:正常情况下是酱紫,但也有可能某一个行代码throw an error,这样就会被阻塞。咦,阻塞是什么呢,且看下面~]。 - [
多线程]多线程就是有多条顺序执行流“同时”执行,且它们之间互不干扰。比如,我们的web网站后台,如果只支持单线程,那么同时只能有一个用户访问站点,你说这点现实吗?答案是肯定的。因此,我们应该为每一个用户创建一个线程,使每个用户能“同时”访问站点。[同时:专业的术语应该叫并发]。
by the way,我们也看下
并发与并行,嗯,虽然这并不是重点... 并发: 是指,同一时刻只能有一条指令(或一个进程、一个线程)运行,但由于CPU的轮换执行速度超乎想象,在宏观上看,就有多条指令同时执行的效果 并行:是同一时刻有多条指令在多个处理机上同时执行。
两者之间的区别
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
- 简而言之,一个程序至少有一个进程,一个进程至少有一个线程。
- 线程的划分尺度小于进程,使得多线程程序的并发性高。
- 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
- 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
- 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
阻塞与非阻塞
概念
阻塞和非阻塞这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的。
-
阻塞调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务。函数只有在得到结果之后才会返回。note: [区别于同步] 对于同步调用来说,很多时候当前线程可能还是激活的,只是从逻辑上当前函数没有返回而已,此时,这个线程可能也会处理其他的消息
-
非阻塞指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回
虽然表面上看非阻塞的方式可以明显的提高CPU的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的CPU执行时间能不能补偿系统的切换成本需要好好评估。
同步与异步
概念
同步:所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。异步: 异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。消息通知: 异步的概念和同步相对。当一个同步调用发出后,调用者要一直等待返回消息(结果)通知后,才能进行后续的执行;当一个异步过程调用发出后,调用者不能立刻得到返回消息(结果)。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
这里提到执行部件和调用者通过三种途径返回结果:状态、通知和回调。使用哪一种通知机制,依赖于执行部件的实现,除非执行部件提供多种选择,否则不受调用者控制。
阻塞与非阻塞,和同步异步无关,可以阻塞等待同步执行过程完成,也可以阻塞等待异步执行过程完成。根据以上理解, 阻塞与非阻塞/同步与异步是可以相互组合的。
-
同步阻塞
调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程需要等待,操作执行完成后返回结果。
-
同步非阻塞 调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程需要等待执行完成才返回结果。
-
异步阻塞 调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。
首先需要明确: 异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。
-
异步非阻塞 调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。
举个🌰
鄙人很爱看电影,于是乎就拿下载电影来说事儿吧O(∩_∩)O哈哈~
- 同步阻塞:我一直抱着ipad,盯着它的下载进度条,直到 100% 才算完成。
同步体现:等待下载完成通知;
阻塞体现在: 等待下载完成通知过程中,不能做其他任务处理。
- 同步非阻塞: 我点击下载任务后就去洗衣服(嗯,我还是很勤劳滴~),每过一段时间就去瞄一眼进度条,看到100%就算完成。
同步体现在:等待下载完成通知
非阻塞体现在:等待下载完成通知过程中,去干别的任务了,只是时不时会瞄一眼进度条。
- 异步阻塞 我换了个有下载完成通知功能的软件,下载完成就“叮”一声。不过我仍然一直等待“叮”的声音 [似不似很傻(⊙o⊙)…]。
异步体现在:下载完成“叮”一声通知;
阻塞体现在:等待下载完成“叮”一声通知 过程中,不能做其他任务处理;
- 异步非阻塞:仍然是那个会“叮”一声的下载软件,我提交下载任务后就去干别的,听到“叮”的一声就知道完成了。
异步体现在:下载完成“叮”一声通知;
非阻塞体现在:等待下载完成“叮”一声通知过程中,去干别的任务了,只需要接收“叮”声通知即可;[软件处理下载任务,我处理其他任务,不需关注进度,只需接收软件“叮”声通知,即可]