Go语言: 万物皆异步
来源:https://www.jianshu.com/p/62c0cd107da3
同步和异步、阻塞和非阻塞
首先要明确的是,同步(Synchronous)和异步(Asynchronous),阻塞(Blocking)和非阻塞(Non-Blocking)是两种完全不同的概念。前者指的是一种事件通知、处理机制,而后者则是程序控制流程的差异。
我们以A调用B为例来说明两者之间的区别:
阻塞
只有当B任务完成后,程序控制权才会返回给A, A得以继续执行。非阻塞
B马上返回,此时B并没有完成,但A可以继续执行,B任务并不影响
A的执行。同步
A需要通过某种方式主动查询B是否完成。在blocking模式中,它表现为等待B返回;在non-blocking模式中表现为通过Future对象询问B是否完成,如果完成则取出结果,未完成则等待(阻塞)。异步
A在启动B任务时就不管了,继续执行自己的任务,当B完成时,由操作系统主动通知A,告知B已经完成。A可以在适宜的时候取出B的执行结果。在这种模式下,A完全不会因为B的执行而影响自己。
异步是解决web应用高并发的唯一方案
“传统的”一线程对一请求的模型直接决定了单机并不能处理过多的并发请求,而且这种模型下会导致很大的线程资源浪费。这里面原因有二:一是每条线程占用要使用较多的内存,在JVM中每创建一个线程就要消耗2M多的heap,于是内存大小就变成线程数量的瓶颈;二是当线程数据超过CPU核心数时,频繁的线程切换会变成一笔可观的开销,而且当你的程序因为查询数据库、执行RPC调用阻塞当前线程时,这个线程是完全不能运行的,不仅白白占用了内存,还增加了Context Switch的次数。
异步并不能加快你对于单个请求的处理速度,但是它能最大化的消灭资源浪费,从而大大提高单机并发极限。
Go的世界中,万物皆异步
Go中只有协程,而协程本质上就是异步。
为什么这么说呢?首先我们知道,协程(routine)跟线程是多对一的关系,routine本身不会被调度执行,它只能依靠操作系统的线程来运行。一个线程可以执行多个routine, Go运行时调度器负责进行调度处理。routine只有三种情况需要让出执行权,分别是system call, 锁竞争和主动让出执行权力。
system call
当发生系统调用时,执行当前routine的线程会block这是没得商量的,但go运行时会从它维护的线程池中取出一条空闲线程继续执行其它routine, 这样就做到了即使你block了routine,也不会影响其它routine的执行。这里可以类比于Netty中的I/O线程,如果你代码block了,则会卡住其他任务的执行,否则你必须在自己的线程池中执行会产生block的代码。网络I/O
调用net包下的网络I/O操作是不会阻塞线程的。当发起网络I/O请求时,go运行时会通过操作系统提供的epoll机制注册I/O事件,不会挂起实际干活的线程,只会切换goroutine而已。竞争
无论是锁竞争还是读写channel而导致routine被挂起,其背后的线程都是不会有任何block的,在OS看来线程一直在正常运行,从而大大降低了线程上下文切换的开销。主动让出执行权
同上面的竞争,主动让出执行权时背后的线程同样不会block。
仔细想想看,这跟前面讲的异步不是几乎一样的逻辑吗?区别是,Go语言中是Go自己的调度器来通知routine等待的IO事件是否完成,而其它非协程语言则是OS来通知。
因此,Go中我们虽然在以同步的方式编写代码,但却与异步有着异曲同工之妙。
Go语言: 万物皆异步的更多相关文章
- 万物皆有始有终: Hawk5即日起停止升级迭代
从即日起,Hawk将停止升级工作,其版本号将停留在5. https://github.com/ferventdesert/Hawk Hawk已经开发和维护6年时间了,它曾经承载了开发者很多的期待.背后 ...
- Javascript万物皆对象?
在javascript的世界里,有这么一句话,万物皆对象. 但是这个对象,应该怎么理解呢? exm........??,难道值类型也是对象?!! 当然,不是. 准确地讲是对于“引用类型”而言. 那,在 ...
- 20190814 On Java8 第三章 万物皆对象
第三章 万物皆对象 对象创建 数据存储 有5个不同的地方可以存储数据: 寄存器 (Registers) 最快的存储区域,位于CPU内部 .无法直接控制. 栈内存(Stack) 存在于常规内存 RAM ...
- C#实现一个万物皆可排序的队列
需求 产品中需要向不同的客户推送数据,原来的实现是每条数据产生后就立即向客户推送数据,走的的是HTTP协议.因为每条数据都比较小,而数据生成的频次也比较高,这就会频繁的建立HTTP连接,而且每次HTT ...
- 万物皆可集成系列:低代码释放用友U8+深度价值(2)—数据拓展应用
在上一篇内容我们介绍了如何利用低代码开发套件实现低代码应用与U8+系统的对接集成,本次给大家带来的是如何将用友U8+系统中的数据进行价值扩展和实际应用. 我们以生产物料齐套分析为例来说明如何利用低代码 ...
- javascript是脚本语言?javascript万物皆对象?
呵呵哒!带你见识下js面对对象的魅力 是的是的,退后,朕要开始装逼了- 这是什么鸟东西?是的是的,装逼开始,2016年度最佳JS编译器,ES6标准出来后,小伙伴们对新特性摩拳擦掌,奈何浏览器支持把我们 ...
- 大话JS面向对象之开篇万物皆对象------(ATM取款机引发的深思)
一,总体概要 OO(面向对象)概念的提出是软件开发工程发展的一次革命,多年来我们借助它使得很多大型应用程序得以顺利实现.如果您还没有掌握并使用OO进行程序设计和开发,那么您无疑还停留在软件开发的石器时 ...
- 万物皆对象的JavaScript
写在前面: 经过前段时间对于H5语言的学习,开始慢慢适应现在的生活节奏和代码语言.从一开始的毫无头绪到现在可以大概地写出部分的网站静态页面,用了两个周的时间.作为一个之前从未接触过计算机语言的初学者来 ...
- Python赋值原理:Python无变量,万物皆对象
有几个和以前的常见语言,比如c语言不同 改变变量数据不覆盖原来的 name = '苍老师' print(id(name)) name = '志玲' print(id(name)) 运行结果 73955 ...
随机推荐
- 用c#判断回文数和降序数
题目:编一个程序,输入一个正整数,判定它是否为回文数和降序数.当输入的数为0时,则退出程序,否则继续循环执行程序. 所谓“降序数”是指一个自然数的低位数字不大于高位数字的数.例如: 64, 55, 3 ...
- pycharm文件名颜色代表的含义
在使用pycharm过程中,文件名有不一样的颜色. 绿色:已经加入版本控制暂未提交 红色:未加入版本控制 蓝色:加入版本控制,已提交,有改动 白色:加入版本控制,已提交,无改动 灰色:版本控制已忽略文 ...
- 剑指Offer系列之题1~题5
目录 1.二维数组的查找 2.替换空格 3.从尾到头打印链表 4.链表中环的入口节点 5.重建二叉树 写在前面:本随笔中包含五道题:题目描述,题目思路以及对应解法. 1.二维数组的查找 在一个二维数组 ...
- C++模板心得
C++模板心得 我开始学模板的时候一脸懵逼,真的看不懂模板是怎么作用的.因为大多数人的代码把模板声明和函数.类的声明分行写,让我以为模板的作用是全局的,实际上应该像如下理解. 函数模板 templat ...
- 微信小程序之界面交互反馈
交互反馈就是在用户出发某事件之后,给用户一个反馈信息,这要是一个很友好的习惯. 在小程序中是通过一下几种方式实现的: 1.wx.showToast()方法 showToast: function (p ...
- python爬取疫情数据详解
首先逐步分析每行代码的意思: 这是要引入的东西: from os import path import requests from bs4 import BeautifulSoup import js ...
- 家庭版记账本app之常用控件的使用方法
现在先介绍在android开发的时候会用的相关的控件,做一个基本的了解方便我们之后对其进行相关具体的操作.下面是相应额详细情况: TextView android:layout_width 和 and ...
- go 切片重组
我们已经知道切片创建的时候通常比相关数组小,例如: slice1 := make([]type, start_length, capacity) 其中 start_length 作为切片初始长度而 c ...
- MySQL入门,第三部分,学会添加删除数据库
一.建立数据库 create database [if not exists] database_name [create_specification] 注意: 1.if not exists === ...
- Lua 5.3 -- SOL2.0 用户指南 【2】
系列教程指南[1] 注意 在你学习了sol的基础知识之后,建议你如果认为某些东西可以运行,你应该尝试一下.它可能会运行! 以下所有代码均可在sol2教程示例中找到. 断言/先决条件 The imple ...