Golang协程和线程区别
一.进程、线程、协程介绍
进程:系统中所有的应用程序都是以进程(process)的方式运行,是系统进行资源分配和调度的基本单位,每个进程都有自己的独立的地址空间,使得进程之间的地址空间相互隔离。
线程:线程是程序执行流的最小单元上,通常意义上,一个进程由一个到多个线程组成,各个线程之间共享程序的内存空间(包括代码段、数据段、堆等)及一些进程级的资源(如打开的文件和信号)。
协程:协程在Go语言中,由轻量级线程实现,由Go运行时(runtime)管理。
这里特别说明下并发和并行:
- 并发:多线程程序在单核上运行
- 并行:多线程程序在多核上运行
二.协程与进程、线程的区别
1)进程拥有自己的堆栈,不共享堆和栈,是由操作系统进行调度的。
2)线程拥有自己的独立的栈和共享的堆,也是由操作系统进行调度。
3)协程共享堆,不共享栈,协程的调度由用户控制。
三.协程的优点
1)代码编辑简单,可以将异步处理逻辑代码用同步的方式编写,将多个异步操作集中到一个函数中完成。
2)单线程模式,没有线程安全的问题,不需要加锁操作。
3)性能好,协程是用户态线程,切换更加高效。
四.协程比线程轻量分析
一旦我们创建完线程,就无法决定它什么时候获得时间片,什么时候让出时间片,这里都交给了内核。和我们编写协程时可以控制,可控的切换时机和很小的切换代价,从操作系统有没有调度权来看,协程就是因为不需要进行内核态的切换。
1)Go协程调用跟切换比线程效率高
线程并发执行流程:
线程是内核对外提供的服务,应用程序可以通过系统调用让内核启动线程,由内核来负责线程调度和切换,线程在等待IO操作时标为unrunnable状态会触发上下文切换。现代操作系统一般采用抢占式调度,上下文切换一般发生在时钟中断和系统调用返回前,调度器计算当前线程的时间片,如果需要切换就从运行队列中选出一个目标线程,保存当前线程的环境,并且恢复目标线程的运行环境,最典型的就是切换ESP指向目标线程内核堆栈,将EIP指向目标线程上次被调度出时的指令地址。
Go协程并发执行流程:
不依赖操作系统和其提供的线程,Golang自己实现的CSP并发模型实现:M,P,G
Go协程也叫用户态线程,协程之间的切换发生在用户态,在用户态没有时钟中断,系统调用等机制,因此效率高。
2)Go协程占用内存小
执行Go协程只需要极少的栈内存(大概4~5KB),默认情况下,线程栈的大小为1MB。
Goroutine就是一段代码,一个函数入口,以及在堆上为其分配的一个堆栈,所以它非常廉价,我们可以很轻松的创建上万个Goroutine,但它们并不是被操作系统所调度执行。
参考链接:https://chende.ren/2021/10/12151539-go-thread-gmp.html
Golang协程和线程区别的更多相关文章
- Lua 协程和线程区别
协程就是协程,不是线程. CPU执行单位是线程,不是什么协程. 协程,是同步执行,不是并行,只是切了一个上下文了,为你保存原来的上下文而已. 切到第二个协程时,原来的协程处于挂起状态. 这个特指lua ...
- 关于协程:nodejs和golang协程的不同
nodejs和golang都是支持协程的,从表现上来看,nodejs对于协程的支持在于async/await,golang对协程的支持在于goroutine.关于协程的话题,简单来说,可以看作是非抢占 ...
- 面试必问:Golang高阶-Golang协程实现原理
引言 实现并发编程有进程,线程,IO多路复用的方式.(并发和并行我们这里不区分,如果CPU是多核的,可能在多个核同时进行,我们叫并行,如果是单核,需要排队切换,我们叫并发) 进程和线程的区别 进程是计 ...
- golang协程同步的几种方法
目录 golang协程同步的几种方法 协程概念简要理解 为什么要做同步 协程的几种同步方法 Mutex channel WaitGroup golang协程同步的几种方法 本文简要介绍下go中协程的几 ...
- Python与Golang协程异同
背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...
- Golang协程实现流量统计系统(3)
进程.线程.协程 - 进程:太重 - 线程:上下文切换开销太大 - 协程:轻量级的线程,简洁的并发模式 Golang协程:goroutine Hello world package main impo ...
- unity3D中协程和线程混合
这是我google unity3D一个问题偶然发现的在stackflow上非常有趣的帖子: 大意是 要在unity3D上从server下载一个zip,并解压到持久化地址.并将其载入到内存中.以下展示了 ...
- day37协程与线程套接字通讯
协程与线程套接字通讯基于多线程实现套接字服务端支持并发,服务端 from socket import * from threading import Thread def comunicate(con ...
- paip.提升性能---协程“微线程”的使用.
paip.提升性能---协程的使用. 近乎无限并发的"微线程" 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...
- I/O多路复用、协程、线程、进程
select注册fd,阻塞,当有fd状态改变时返回,确认对应的fd,做下一步处理.简单来说就是先注册,注册完后休眠并设置一个定时器醒来查看,有事件就通知来取,进行后续动作,没事件就继续睡,再设闹钟.用 ...
随机推荐
- 我觉得 AI 你过分了!
大家好,我是程序员鱼皮.创业之后,头发掉的厉害,已经记不清自己头发茂密如林的时候了... 正好最近 AI 工具 Gemini 新出了原生多模态生图功能,于是便想借助 AI 来生成一张 "鱼皮 ...
- GBJ 97-1987 水泥混凝土路面施工及验收规范(电子版)PDF 版本 下载
本规范适用于新建和改建的公路 城市道路 厂矿道路和民航机场道面等就地浇筑的水泥混凝土路面的施工及验收 链接:https://pan.baidu.com/s/17t88jnEU6IrptmEWsyuN3 ...
- NodeJS运行时抛出: Error: listen EADDRINUSE :::3000
错误详情Error: listen EADDRINUSE :::3000 at Server.setupListenHandle [as _listen2] (net.js:1360:14) ...
- 异常--java进阶day08
1.异常 java中,所有的异常都是类 2.异常的体系结构 3.编译时异常与运行时异常 1.编译时异常 语法完全正确,但是代码就是会报错,如下图 上图中,写的是时间格式化类的使用,parse方法将给的 ...
- 继承内存图--java进阶 day01
主方法进栈,有new进堆 堆内存中先存自己类中有的变量 又因为继承了父类,所以父类中的变量也要存入 即使被私有化,依旧可以继承,只是没有权限使用! 创建对象时,会调用构造方法,所以走构造方法,实参传形 ...
- Windows Terminal
... Windows Terminal 安装 命令行接口 Windows Terminal 的命令行接口是 wt 因此我们可以在运行输入 wt 打开 Windows Terminal 也可以在资源管 ...
- leetcode每日一题:使字符串平衡的最小交换次数
引言 今天开始,打算做一个新的系列:leetcode每日一题的题解.预期每天用90分钟的时间,去写一篇当天的每日一题的题解,这个目标跟早起结合在一起,才有足够的时间完成.其实早在前几年,就开始断断 ...
- CyclicBarrier的await()方法底层原理
一.定义 CyclicBarrier 的 await() 方法是其核心功能之一,用于让线程在屏障点等待,直到所有参与的线程都到达屏障后,才能继续执行. 其底层实现依赖于 AQS(AbstractQue ...
- Redis底层数据结构 链表
链表 Redis 的 List 对象的底层实现之一就是链表.C 语言本身没有链表这个数据结构的,所以 Redis 自己设计了一个链表数据结构. 链表节点结构设计 先来看看「链表节点」结构的样子: ty ...
- 基于 OT-JSON 与 Immer 设计低代码/富文本场景的状态管理方案
在复杂应用中,例如低代码.富文本编辑器的场景下,数据结构的设计就显得非常重要,这种情况下的状态管理并非是redux.mobx等通用解决方案,而是需要针对具体场景进行定制化设计,那么在这里我们来尝试基于 ...