阅读 342

线程,进程,js 单线程,ios多线程本质

什么是进程?

进程:是cpu分配资源的最小单位;(是能拥有资源和独立运行的最小单位)

什么是线程?

线程:是cpu调度的最小单位;(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)

线程与进程有什么区别?

线程是指程序在执行过程中,能够执行程序代码的一个执行单元。线程主要有四种状态:运行、就绪、挂起、结束。
进程是指一段正在执行的程序。而线程有时候也被称为轻量级进程,是程序执行的最小单元,一个进程可以拥有多个线程,各个线程之间共享程序的内存空间(代码段、数据段和堆空间)及一些进程级的资源(例如打开的文件),但是各个线程拥有自己的栈空间,

线程与进程的比喻

进程就是一个公司,每个公司都有自己的资源可以调度;公司之间是相互独立的;而线程就是公司中的每个员工(你,我,他),多个员工一起合作,完成任务,公司可以有一名员工或多个,员工之间共享公司的空间

多线程的实现原理

事实上,同一时间内单核的CPU只能执行一个线程,多线程是CPU快速的在多个线程之间进行切换(调度),造成了多个线程同时执行的假象。
如果是多核CPU就真的可以同时处理多个线程了。

JS单线程的概念

  • 单线程指的是程序执行过程中只有一个有效操作的序列,不同操作之间都有明确的执行先后顺序
  • JS 代码被JS引擎执行的时候是单线程的,同一时刻有且仅有一处代码正在执行,同一个时间只能做一件事,并阻塞其它的代码。

单线程这样命名很不方便?为什么要这样设计?这事有一定原因的。

JS作为浏览器的脚本于是,其最根本的作用就是实现用户与浏览器的交互行为,当一个用户要删除一个A,又同时向A中添加内容的时候,若是多线程,应该怎么样去处理?没有办法处理,若是单线程就很简单了,用户先执行那个操作,我们主线程就进行哪一个,不会出现任何冲突!

js单线程为什么会异步

异步的任务,是由浏览器的其他线程去完成的。

  • 例如有一个异步任务buyFruit,那我如何在他买到水果后再进行其他操作呢,比如我需要吃买到的水果,可以这样做,将eat函数当作buyFruit函数的一个参数传进去即可,这样当buFruit有结果的时候,eat就可以对这个异步结果进行处理了,这里,eat函数就回调。
  • 回调是什么?也许你看过各种概念,被搞的晕头转向,还有举的各种形象的例子。其实,我觉得很多东西不要去理解概念,你知道它是什么,它的作用是什么,这些概念其实没什么作用,如果你非要问什么是回调,首先,回调是函数,这个函数被当作一个参数传给另一个函数。就这么简单。
  • 用回调函数获取异步的结果,存在一些问题,比如,当你还有更多的异步操作后,会很难处理,这就出现了一些其他的方法解决,比如Promise。

js单线程跟异步的解析

没错,JS是单线程,但是JS是在浏览器中运行的脚本语言,它的宿主,浏览器可不是单线程的,这时候,大家又会产生疑问,这两者之间有什么关系呢?下面我们就来讲讲:

单线程只有前一个任务结束,才能执行下一个任务。如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。

JS语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。 于是呢,任务就被分成两种,一种是同步任务,一种是异步任务
同步任务:只有前一个任务执行完成后,才可执行下一个任务,在主线程中
异步任务:这个队列的所有任务都是不进入主线程执行,而是被浏览提供的线程执行,当执行完毕后就会产生一个回调函数,并且通知主线程,在主线程执行完当前所执行的任务后,就会调取最早通知自己的回调函数,使其进入主线程中执行,比如ajax请求,再主线程中呈现的就是请求结果~

js 是怎么处理任务

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。 (2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件(回调函数callback)。 (3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。(  4)主线程不断重复上面的第三步。

任务队列

“任务队列”是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在”任务队列”中添加一个事件,表示相关的异步任务可以进入”执行栈”了。主线程读取”任务队列”,就是读取里面有哪些事件。

“任务队列”中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入”任务队列”,等待主线程读取。

回调函数

所谓”回调函数”(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。

“任务队列”是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,”任务队列”上第一位的事件就自动进入主线程。但是,由于存在后文提到的”定时器”功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。

文章分类
前端
文章标签