目录

协程概念简要理解

为什么要做同步

协程的几种同步方法

Mutex

channel

WaitGroup


协程概念简要理解

协程类似线程,是一种更为轻量级的调度单位,但协程还是不同于线程的,线程是系统级实现的,常见的调度方法是时间片轮转法,如每隔10ms切换一个线程执行。

协程则是应用软件级实现,它和线程的原理差不多,当一个协程调度到另一个协程时,将上一个协程的上下文信息压入堆栈,来回切换。一个线程可以跑很多个协程,由这个线程来调度协程的切换,如果是C/C++的话底层就能通过select/poll/epoll来做,例如微信后台的开源libco库。

golang协程底层不是C,纯go实现,golang的协程应该是目前各类有协程概念的语言中实现的最完整和成熟的,调度是基于GPM模型实现的,有兴趣可以去了解下,这里不扯远了,下面看看协程的同步。

为什么要做同步

至于为什么需要同步呢,类似线程要做同步差不多,现在的cpu都是多核,假设一核一个线程同时一起访问同一块内存中的数据吗,那么可能上一ns第一个线程刚把数据从寄存器拷贝到内存,第二个线程马上又把此数据用它修改的值给覆盖了,这样共享数据变会乱套。

举个例子 :

用2个协程序并发各自增一个全局变量100 0000 次

package main import("fmt""time"
)var share_cnt uint64 = 0func incrShareCnt() {for i:=0; i < 1000000; i++ {share_cnt++}fmt.Println(share_cnt)
}func main()  {for i:=0; i < 2; i++ {go incrShareCnt()}time.Sleep(1000*time.Second)}

运行4次 , 可以看到我们虽然自增了200 0000次,但没有一个输出200 0000的结果.

协程的几种同步方法

Mutex

互斥锁,可以创建为其他结构体的字段;零值为解锁状态。Mutex类型的锁和线程无关,可以由不同的线程加锁和解锁。

package mainimport("fmt""time""sync"
)var share_cnt uint64 = 0var lck sync.Mutexfunc incrShareCnt() {for i:=0; i < 1000000; i++ {lck.Lock()share_cnt++lck.Unlock()}fmt.Println(share_cnt)
}func main()  {for i:=0; i < 2; i++ {go incrShareCnt()}time.Sleep(1000*time.Second)}

channel

使用golang的channel, 下面一个典型的生产消费模型

package main import("fmt""time""strconv"
)func main() {msg_chan := make(chan string)done     := make(chan bool)i := 0go func() {for  {i++time.Sleep(1*time.Second)msg_chan <- "on message"<- done}}()go func() {for {select {case msg := <- msg_chan :i++fmt.Println(msg + " " + strconv.Itoa(i))time.Sleep(2*time.Second)done <- true}}}()time.Sleep(20*time.Second)
}

WaitGroup

sync包中的WaitGroup可用等待一组协程的结束。
父协程通过Add方法来设定应等待的线程的数量。
每个被等待的协程在结束时调用Done方法。
同时,主协程里调用Wait方法阻塞至所有线程结束。

package mainimport("sync""net/http"
)var wg sync.WaitGroup
var urls = []string{"http://www.baidu.com/","http://www.taobao.com/","http://www.tianmao.com/",
}
func main() {for _, url := range urls {// Increment the WaitGroup counter.wg.Add(1)// Launch a goroutine to fetch the URL.go func(url string) {// Decrement the counter when the goroutine completes.defer wg.Done()// Fetch the URL.http.Get(url)}(url)
}
// Wait for all HTTP fetches to complete.
wg.Wait()}

golang 协程同步 简介相关推荐

  1. golang协程goroutine简介

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

  2. GoLang协程与通道---下

    GoLang协程与通道---下 新旧模型对比:任务和worker 惰性生成器的实现 实现 Futures 模式 复用 典型的客户端/服务器(C/S)模式 卸载(Teardown):通过信号通道关闭服务 ...

  3. Python与Golang协程异同

    背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...

  4. golang 数组 最后一个_面试必问:Golang高阶Golang协程实现原理

    1 01 引言 实现并发编程有进程,线程,IO多路复用的方式.(并发和并行我们这里不区分,如果CPU是多核的,可能在多个核同时进行,我们叫并行,如果是单核,需要排队切换,我们叫并发). 1.1 进程和 ...

  5. go 怎么等待所有的协程完成_怎么关闭golang协程

    怎么关闭golang协程 发布时间:2020-06-10 10:43:33 来源:亿速云 阅读:284 作者:Leah 这篇文章给大家分享的是关闭golang协程的方法.小编觉得挺实用的,因此分享给大 ...

  6. 深入浅出 Golang 协程池设计

    使用Go语言实现并发的协程调度池阉割版,本文主要介绍协程池的基本设计思路,目的为深入浅出快速了解协程池工作原理,与真实的企业协程池还有很大差距,本文仅供学习参考. 一.何为并发,Go又是如何实现并发? ...

  7. Golang 协程的使用方法

    Golang 协程正确的使用方法 错误的使用方法 package main // 错误使用案例 import ("time""fmt" ) var c1 cha ...

  8. Golang 协程顺序打印

    Golang 协程顺序打印 A.B 两个协程分别打印 1.2.3.4 和 A,B,C,D 实现:定义 A.B 两个 channal,开 A.B 两个协程,A 协程输出[1, 2, 3, 4].B 协程 ...

  9. golang协程分段下载文件

    目录 golang协程 加锁示例 golang协程分段下载文件 golang协程 golang协程分段下载文件,为了提升性能,更好的利用golang协程的特性,我们开始使用他测试一下我们的程序 gol ...

最新文章

  1. Python_基础_6
  2. 在eclipse中运行工程时 出现出现ConnectionProperties 的解决方法
  3. Delphi 与C系列区别之已见(一)
  4. vmware服务器虚拟化部署sdn,使用VMware的NSX多面落地软件定义网络SDN视频课程
  5. 如何保证进程间同步工作_冬季建房如何保证混凝土浇筑效果好,做好养护工作...
  6. php生成excel到服务器,yii phpexcel自动生成文件保存到服务器上
  7. 【数据结构与算法】算法的时间复杂度
  8. 普通人如何走上复利投资致富的门路?
  9. JMeter性能测试-安装与入门
  10. Javascript数据类型转换第六课
  11. 百度翻译API 错误码: 52003,错误信息: UNAUTHORIZED USER
  12. 模块化机房建设指导书_模块化机房建设方案.doc
  13. A00工具类学习之参考文献写法
  14. 危化品企业双预防机制数字化建设综合解决方案
  15. MATLAB矩阵的建立
  16. 移动端大规模草渲染的实现(精简版)
  17. 计算机测试是指,考驾照电脑测试是什么
  18. python设计模式名片_Python设计模式之门面模式简单示例
  19. 阿里的“传奇程序员”
  20. 甲方安全之仿真钓鱼演练(邮件+网站钓鱼)

热门文章

  1. [zz]Apache Thrift学习小记
  2. android中DatePickerTimePicker的应用
  3. 5G + 边缘计算系列文章
  4. IPv6 — IPv4v6 综合组网技术
  5. C 语言编程 — 高级数据类型 — 指针
  6. openstack nova 源码解析 — Nova API 执行过程从(novaclient到Action)
  7. ARMS V4.3发布,应用监控全新支持内存快照分析,全息排查等功能。
  8. asp.net core选项配置的研究
  9. 强大的表格控件handsometable,结合vue
  10. 刷牙刷了这么多年,我们居然都搞错了!