golang多协程的同步方法总结_第1页
golang多协程的同步方法总结_第2页
golang多协程的同步方法总结_第3页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

golang多协程的同步⽅法总结之前⽤go写⼀个⼩⼯具的时候,⽤到了多个协程之间的通信,当时随⼿查了查,结果查出来⼀⼤坨,简单记录⼀下.golang中多个协程之间是如何进⾏通信及数据同步的嘞.共享变量⼀个最简单,最容易想到的,就是通过全局变量的⽅式,多个协程读写同⼀个变量.但对同⼀个变量的更改,就不得不加锁了,否则极易引发数据问题.⼀般系统库都提供基本的锁,go也提供了.packagemainimport("fmt""sync""time")varnum=0//互斥锁varmutex=sync.Mutex{}//读写锁varrwMutex=sync.RWMutex{}funcmain(){fori:=0;i<100;i++{goincrNum()}time.Sleep(2)fmt.Println(num)}funcincrNum(){mutex.Lock()num=num+1mutex.Unlock()}仅执⾏⼀次当查询锁查到sync这个模块时,发现它下⾯的对象并没有⼏个,都是针对协程同步的各个⽅⾯给出的解决⽅案.所以我就⼀个⼀个看⽂档试了试.当你需要对环境,连接池等等资源进⾏初始化时,这种操作只需要执⾏⼀次,这时候就需要它了.sync.Once对象可以保证仅执⾏⼀次.和init⽅法有些类似,不过init⽅法是在模块⾸次加载时执⾏,⽽sync.Once是在⾸次调⽤时执⾏.(其实现就是⼀个计数器加⼀个互斥锁)packagemainimport("fmt""sync""time")varnum=0varonce=sync.Once{}funcmain(){fori:=0;i<100;i++{goonce.Do(incrNum)}time.Sleep(2)fmt.Println(num)}funcincrNum(){num=num+1}等待其他协程处理某个协程需要等第⼀阶段的所有协程处理完毕,才能开始执⾏第⼆阶段.这个时候,等待其他协程就可以通过sync.WaitGroup来实现.(当然,也可以通过⼀个共享计数器变量来实现).packagemainimport("fmt""sync")varwaitGroup=sync.WaitGroup{}funcmain(){fori:=0;i<100;i++{goincrNum()}//等待其他协程处理完毕(共享变量为0)waitGroup.Wait()fmt.Println("don")}

funcincrNum(){//增加需要等待的协程数量(共享变量+1)waitGroup.Add(1)//dosomething//标记当前协程处理完成(共享变量-1)waitGroup.Done()}消息通知多个协程启动时,等待某个命令到来时执⾏命令,唤醒等待协程.go对此类操作也进⾏了处理,感觉好贴⼼哦.但是经过测试,即使没有空闲的协程,唤醒命令同样能够发出去,所以需要注意⼀下.packagemainimport("sync")varmutex=&sync.Mutex{}varcond=sync.NewCond(mutex)funcmain(){fori:=0;i<100;i++{goincrNum()}//发送命令给⼀个随机获得锁的协程cond.Signal()//发送命令给所有获得锁的协程cond.Broadcast()}funcincrNum(){//获取锁,标识当前协程可以处理命令cond.L.Lock()//可添加退出执⾏命令队列的条件fortrue{//等待命令cond.Wait()//dosomething}//释放锁,标记命令处理完毕,退出协程cond.L.Unlock()}多协程map普通的map在多协程操作时,是不⽀持并发写⼊的.go贴⼼的给封装了⽀持并发写⼊的map.同时也提供了针对map的基本操作.packagemainimport("fmt""sync""time")varm=sync.Map{}funcmain(){fori:=0;i<100;i++{gofunc(){m.Store("1",1)}()}time.Sleep(time.Second*2)//遍历mapm.Range(func(key,valueinterface{})bool{//返回false结束遍历returntrue})//读取变量,若不存在则设置m.LoadOrStore("1",3)//删除keym.Delete("1")//读取变量load,_:=m.Load("1")fmt.Println(load)}多协程对象池对于数据库连接池应该并不陌⽣.⽽sync.Pool对象是go封装的协程安全的对象池.对象池的使⽤⼗分简单,存/取packagemain

import("sync")varp=sync.Pool{//当池⼦中没有对象了,⽤于创建新对象New:func()interface{}{return"3"},}funcmain(){//从池⼦中获取⼀个对象r:=p.Get()//⽤完后将对象放回池⼦中p.Put(r)}sync简单总结针对go系统的sync模块,提供的基础功能如下:互斥锁Mutex读写锁RWMutex函数单次执⾏Once协程执⾏等待WaitGroup协程消息通知Cond多协程mapMap多协程对象池Pool⼏个都简单试过之后,发现sync模块针对常⽤的⼏个多

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论