golang并发编程的实现
go
main函数的执行本身就是一个协程,当使用go关键字的时候,就会创建一个新的协程
channel
channel管道,用于在多个协程之间传递信号
无缓存管道
当对无缓冲通道写的时候,会一直阻塞等到某个协程对这个缓冲通道读
阻塞场景:
- 通道中无数据,但执行读通道。
- 通道中无数据,向通道写数据,但无协程读取。
综上,无缓存通道的读写必须同时存在,且读写分别在两个不同的协程
funcmain(){ ch:=make(chanint) gofunc(chchanint){ ch<-222 }(ch) println(<-ch) }
有缓冲管道
有缓存时可以向通道中写入数据后直接返回,缓存中有数据时可以从通道中读到数据直接返回,这时有缓存通道是不会阻塞的
阻塞场景:
- 通道的缓存无数据,但执行读通道。
- 通道的缓存已经占满,向通道写数据,但无协程读。
综上,有缓冲通道的读写必须在两个不同协程
funcmain(){ ch:=make(chanint,1)//长度为1的缓冲管道也是有缓冲管道 ch<-333 gofunc(chchanint){ println(<-ch) }(ch) ch<-333 }
sync.Mutex和sync.RwMutex
sync.Mutex并发锁,一次只可以加载一个并发锁
sync.RwMutex读写锁,一次可以加载多个读锁和一个写锁。当写锁存在时候,不能再加载读锁和写锁
sync.WaitGroup
阻塞等待所有任务完成之后再继续执行
WaitGroup在不方法中传递,需要传指针
funcmain(){ varwgsync.WaitGroup ch:=make(chanint,1000) fori:=0;i<1000;i++{ wg.Add(1) godoSomething(i,&wg,ch) } wg.Wait() fmt.Println("alldone") fori:=0;i<1000;i++{ dd:=<-ch fmt.Println("fromch:"+strconv.Itoa(dd)) } } funcdoSomething(indexint,wg*sync.WaitGroup,chchanint){ deferwg.Done() fmt.Println("startdone:"+strconv.Itoa(index)) //time.Sleep(20*time.Millisecond) ch<-index }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。