Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

基于单线程的事件轮询 #16

Open
CoolRabbit520 opened this issue Mar 13, 2018 · 0 comments
Open

基于单线程的事件轮询 #16

CoolRabbit520 opened this issue Mar 13, 2018 · 0 comments

Comments

@CoolRabbit520
Copy link
Owner

单线程

程序、进程、线程

  • 程序:由源代码生成的可执行应用。 (例如:QQ.app)

  • 进程:一个正在运行的程序可以看做一个进程,(例如:正在运行的QQ警示),进程拥有独立运行所需要的全部资源

  • 线程:程序中独立运行的代码段。(例如:接收QQ消息的代码)

一个进程是由一或多个线程组成,进程只负责资源的调度和分配,线程才是程序真正的执行单元,负责代码的执行。

单线程

每个正在运行的程序(即进程),至少包括一个线程,这个线程叫主线程

主线程在程序启动时被创建,用于执行main函数

只有一个主线程的程序,称作单线程程序

主线程负责执行程序的所有代码(UI展现以及刷新,网络请求,本地存储等等)。这些代码只能顺序执行,无法并发执行

多线程

拥有多个线程的程序,称作多线程程序。

iOS允许用户自己开辟新的线程,相对于主线程来讲,这些线程,称为子线程

可以根据需要开辟若干子线程

子线程和主线程都是独立的运行单元,各自的执行互不影响,因此能够并发执行

单线程、多线程的区别

单线程程序:只有一个线程,代码顺序执行,容易出现代码阻塞(页面假死)

多线程程序:有多个线程,线程间独立运行,能有效地避免代码阻塞,并且提高程序的运行性能

注意:iOS中关于UI的添加和刷新必须在主线程中操作

事件轮询Event Loop

详见JS中的异步以及事件轮询机制
事件驱动
单线程
事件轮询
异步I/O
非阻塞:事件循环的一个好处就是让JS从来不阻塞,我们一般通过事件和回调去操作,所以当应用在等待一个IndexedDB查询返回或者一个XHR请求返回的时候,主线程仍然可以处理其他事情比如用户输入。
无论何时某个函数一旦开始运行,那么它就不可能被别的代码打断运行。

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

  • JS的异步是通过回调函数实现的。
  • 当主线程开始执行异步任务,就是执行对应的回调函数 。
  • Javascript线程包括一个储存了待执行任务的消息列表的消息队列,以及与它们相关联的回调函数,这些消息按照它们的响应顺序排列(例如鼠标点击,或者收到来自HTTP请求的响应)每条消息都有回调函数,如果没有提供回调函数:例如当用户点击一个按钮但是没有提供回调函数,则没有消息会被添加到消息队列。
  • 虽然JS是单线程的但是浏览器的内核是多线程的,在浏览器的内核中不同的异步操作由不同的浏览器内核模块调度执行,异步操作会将相关回调添加到任务队列中。而不同的异步操作添加到任务队列的时机也不同。
    • onclick 由浏览器内核的 DOM Binding 模块来处理,当事件触发的时候,回调函数会立即添加到任务队列中。

    • setTimeout 会由浏览器内核的 timer 模块来进行延时处理,当时间到达的时候,才会将回调函数添加到任务队列中。

    • ajax 则会由浏览器内核的 network 模块来处理,在网络请求完成返回之后,才将回调添加到任务队列中。

异步同步与阻塞非阻塞

异步同步

基于被调用者的**消息通信机制 **。

  • 同步:事件未处理完之前,不会返回,只能让调用者主动等待这个调用的结果。
  • 异步:调用之后立即返回。事件处理完成后,可以通过状态、通知来通知调用者,或通过回调函数处理这个调用。

阻塞非阻塞

主进程等待调用结果(消息,返回值)时的状态。

  • 阻塞:调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
  • 非阻塞:调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

异步是配合非阻塞使用的,这样才能发挥异步的效用。

参考资料

  1. 单线程、多线程的区别 - Running2Snail - 博客园
  2. 浅析JavaScript的并发模型和事件循环
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant