1、协程介绍
        进程和线程都是由操作系统内核进行调度,有 CPU 时间片的概念,进行抢占式调度。
        协程是用户级的线程,对内核是透明的,系统并不知道协程的存在,并且协程是非抢占式调度,无法实现公平的任务调用,通常只进行协作式调度,需要协程自己主动把控制权转让出去之后,其他协程才能被执行到。
在任务调度上,协程弱于线程;

在资源消耗上,协程则是极低的,一个线程的内存在 MB 级别,而协程只需要 KB 级别。

2、协程的的基本原理
        协程是基于线程的,二者的原理一样,线程是在操作系统内核层面实现的,协程是在应用层实现了线程

Go Scheduler会把goroutine调度到逻辑处理器上运行,逻辑处理器会一对一的绑定到操作系统的线程。当goroutine可以运行时,会被放入一个逻辑处理器的待执行队列中;当goroutine遇到长时间执行或执行了一个阻塞的系统调用时(如打开文件),Go Scheduler会将这个逻辑处理器与线程分离,并将另一个线程绑定到这个逻辑处理器,之后从待执行队列中选择下一个goroutine来运行,原来的goroutine保存到待执行队列等待调用(逻辑处理器是不动的)。

每一个goroutine是一个独立的执行单元,相较于每个OS线程固定分配2M内存的模式,goroutine的栈采取了动态扩容方式, 初始时仅为2KB,随着任务执行按需增长,最大可达1GB,且由golang的调度器 Go Scheduler 来调度。此外,GC还会周期性地将不再使用的内存回收,收缩栈空间。

Go Scheduler调度器能管理所有被创建的 goroutine 并为其分配执行时间。Go Scheduler能将语言运行时的逻辑处理器与操作系统的线程一一绑定,并会全面的控制哪个 goroutine 要在哪个逻辑处理器上运行。

3、Goroutine同步机制

Goroutine提供了一种传统的同步机制——对共享资源加锁。
(1)原子函数能够以很底层的加锁机制来同步访问整型变量和指针。
atomic.AddInt64(&counter, 1),强制同一时刻只能有一个 goroutine 运行并完成这个加法操作,还有LoadInt、StoreInt等。
(2)互斥锁用于在代码上创建一个临界区,保证同一时间只有一个 goroutine 可以
执行这个临界区里的代码。

var mutex sync.Mutex
mutex.Lock(){
xxx
}
mutex.Unlock()

(3)通道

使用原子函数和互斥锁能够保证对共享资源的安全访问以及消除竞争状态;
使用通道,通过发送和接收需要共享的资源,在goroutine 之间进行同步。
无缓冲的通道(unbuffered channel):指在接收前没有能力保存任何值的通道。这种类型的通
道要求发送goroutine 和接收goroutine 同时准备好,才能完成发送和接收操作,如果两个goroutine
没有同时准备好,通道会导致先执行发送或接收操作的goroutine阻塞等待。
有缓冲的通道(buffered channel):是一种在被接收前能存储一个或者多个值的通道。不强制要求goroutine 之间必须同时完成发送和接收。只有在通道没有可用缓冲区容纳被发送的值时,发送动作才会阻塞;只有在通道中没有要接收的值时,接收动作才会阻塞。

4、多线程-〉异步编程-〉协程
        线程是操作系统的内核对象,多线程编程时,如果线程数过多,就会导致频繁的上下文切换,这些 cpu 时间是一个额外的耗费。

于是操作系统提供了基于事件模式的异步编程模型,用少量的线程来服务大量的网络连接和I/O操作,但是采用异步和基于事件的编程模型,复杂化了程序代码的编写,非常容易出错,再加上线程穿插,也提高排查错误的难度。

协程是在应用层模拟的线程,避免了上下文切换的额外耗费,兼顾了多线程的优点,简化了高并发程序的复杂度。
5、协程为什么大热?
        主要用于网络编程,其独有的特点。高并发(每秒钟上千数万的单机访问量),程序生命期短(毫秒,秒级) 高IO,低计算(连接数据库,请求API)。
6、实际应用
        在一个函数调用前加上go关键字,这次调用就会在一个新的goroutine中并发执行,当被调用的函数返回时,这个goroutine也自动结束。需要注意的是,如果这个函数有返回值,那么这个返回值会被丢弃。

Golang的协程(goroutine)和同步机制相关推荐

  1. golang协程goroutine

    协程goroutine 概念 协程(英语:coroutine)是计算机程序的一类组件,推广了协作式多任务的子例程,允许执行被挂起与被恢复.相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那 ...

  2. Golang的协程调度器原理及GMP设计思想

    一.Golang"调度器"的由来? (1) 单进程时代不需要调度器 我们知道,一切的软件都是跑在操作系统上,真正用来干活(计算)的是CPU.早期的操作系统每个程序就是一个进程,知道 ...

  3. Golang的协程调度

    调度的基础,模型关系的映射 GPM模型: G,Goroutinue 被调度器管理的轻量级线程,goroutine使用go关键字创建 调度系统的最基本单位goroutine,存储了goroutine的执 ...

  4. 『GoLang』协程与通道

    作为一门 21 世纪的语言,Go 原生支持应用之间的通信(网络,客户端和服务端,分布式计算)和程序的并发.程序可以在不同的处理器和计算机上同时执行不同的代码段.Go 语言为构建并发程序的基本代码块是 ...

  5. golang异步协程调度原理

    golang异步协程调度 在1.14的go版本中,官方通过加入信号来进行协程的调度,后续就都支持了这种异步协程抢占,避免了早起的考栈调度时来检查是否执行超时的逻辑.本文简单来对比这种实现的原理. 调度 ...

  6. go 怎么等待所有的协程完成_GO语言基础进阶教程:Go语言的协程——Goroutine

    Go语言的协程--Goroutine 进程(Process),线程(Thread),协程(Coroutine,也叫轻量级线程) 进程进程是一个程序在一个数据集中的一次动态执行过程,可以简单理解为&qu ...

  7. k8s与监控--从telegraf改造谈golang多协程精确控制

    从telegraf改造谈golang多协程精确控制 前言 telegraf是infuxdb公司开源出来的一个基于插件机制的收集metrics的 项目.整个架构和elastic公司的日志收集系统极其类似 ...

  8. golang协程goroutine简介

    文章目录 goroutine 与thread比较 M:N模型 调度策略 可运行队列 协作式调度 系统调用 同步调用 异步调用 scheduler的陷阱 goroutine是Go语言中的轻量级线程实现, ...

  9. Golang协程goroutine和管道channel结合案例

    管道的遍历和关闭 协程和管道结合案例 需求 思路分析 写数据管道 读数据管道 读完数据后关闭管道,并往exitChain管道中写入数据 主程序

最新文章

  1. centos7下Gitlab+Jenkins部署持续集成CI环境
  2. swift_017(Swift 的枚举)
  3. 数据访问层设计(持久层架构设计)
  4. TypeError: sequence item 0: expected str instance, int found
  5. 字符定长文件Linux怎么生成,Linux中的more命令-逐页显示长文本文件
  6. linux gd结构体,U-Boot中gd的定义和使用
  7. 贝叶斯公式的图形记忆
  8. 深度学习中的激活函数导引
  9. 工商管理专业知识与实务(中级)【4】
  10. 在uniapp的小程序中使用自己的字体库
  11. 绝地求生服务器延迟检测源码,绝地求生不停网络延迟检测怎么办 绝地求生网络问题解决办法...
  12. The following classes could not be found - EditText (Change to android.widget.EditText, Fix Build Pa
  13. 解决 jack server is not running
  14. 服务器匹配原理,王者荣耀实现原理学习笔记
  15. Apt-get 如何在Ubuntu/Debian上正常工作
  16. win10 病毒实时防护 关闭
  17. BIO和NIO消耗的cpu和内存比较
  18. 【天光学术】中国大学英语专业学年论文写作特点
  19. 打印机 检测到用过的耗材或者赝品耗材
  20. shell脚本编程超级群-问题集合--持续更新中

热门文章

  1. zabbix学习笔记(4)
  2. redis开启外网访问
  3. Linux下让进程在后台可靠运行的几种方法
  4. UITableviewcell重用机制以及解决重绘出现的重叠现象
  5. 【Minimum Depth of Binary Tree】cpp
  6. puppet结构图一例
  7. ccaf internship
  8. 【转】volatile关键字。编译器不优化,多线程会改。防止随时变动的
  9. c++动态链接库及静态链接库的生成与使用
  10. 远程桌面Web连接访问及端口更改方法