Golang学习之路6-goroutine并发
创始人
2024-01-30 02:27:11

文章目录

  • 前言
  • 一、goroutine用法
  • 二、goroutine循环
  • 三、goroutine提前退出
  • 四、goroutine双向管道
  • 五、goroutine单向管道
  • 六、监听管道
    • 如下图,可以看到当我们监听到有写入数据时会得到对应的类型数据,当没有写入时 default 一直在负责监听! ![在这里插入图片描述](/uploadfile/202401/6b96fdd3c5bf01c.png)
  • 总结


前言

什么是 goroutine?简称可以使:go程、并发

  • goroutine是与其他函数或方法同时运行的函数或方法。
  • goroutine可以被认为是轻量级线程,天生支持多并发。
  • 与线程相比,创建goroutine的成本很小,因此Go 应用程序通常会同时运行数千个goroutine。

一、goroutine用法

go语言天生支持多并发,使用方式:

  • 方式一:go func()
  • 方式二(匿名):go func(){}()
package main
import ("fmt""time"
)
func display(count int) {for {fmt.Println("这是子go程======>:", count)time.Sleep(1)count++}
}func main() {go display(1)// 匿名 子go程 函数//go func () {//	count := 1//	for {//		fmt.Println("这是子go程======>:", count)//		time.Sleep(1)//		count++//	}//}()// 主go程count := 1for {fmt.Println("这是主go程:", count)count++time.Sleep(1)if count > 2 {break}}
}

可以看到,主进程没有打印第3次,而子进程打印了第3次
在这里插入图片描述

二、goroutine循环

比如起3个进程跑goroutine,cpu资源会被竞争不确定谁先谁后:

for i := 0; i <= 3; i++ {go func() {}()
}

三、goroutine提前退出

三种退出go程方式:

  • return:只退出当前子go程函数
  • runtime.Goexit():只退出当前go程
  • os.Exit(-1):退出所以的主子go程
package mainimport ("fmt""os""time"
)func main() {go func() {func() {fmt.Println("这是子go程 内部函数111")//return 			  // 只结束此函数,会执行到:子go程222//runtime.Goexit()    // 退出当前go程,不会执行到:子go程222os.Exit(-1)	          // 退出所以主子进程}()fmt.Println("子go程222")}()time.Sleep(1)fmt.Println("结束主go程!")
}

四、goroutine双向管道

通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。

ch <- value    // 把 value  发送到通道 ch
value := <-ch  // 从 ch 接收数据,并把值赋给 value 

chan双向管道:

  • 使用通讯时不需要上锁解锁;
  • 未创建容量时是无缓冲的,反之是有缓冲的;
  • 当缓冲区写满时或读取完成时会阻塞,当被读取后再恢复写入;
  • 管道的读与写次数必须对等,否则会被堵塞,①如果阻塞主go程那么程序被锁死至崩溃,②如果阻塞在子go程会出现内存泄漏;
  • 需要使用make分配空间,否则管道默认是nil,读写都会堵塞(和map一样所以建议都是make);
  • 使用goroutine管道时推荐使用for range,当管道写入完成后应关闭close(chan)
package main
import ("fmt""time"
)func main() {// 创建一个容量为10的int有缓冲管道numChan := make(chan int, 10)// 写“管道”数据go func() {for i := 1; i < 21; i++ {numChan <- ifmt.Println("11-->子go程写入数据:", i)}// 写入结束,关闭管道close(numChan)}()// 读“管道”数据go func() {for num := range numChan {fmt.Println("22-->子go程读取数据data:", num)}}()time.Sleep(1 * time.Second)// 判断管道是否关闭for {v, ok := <-numChanif !ok {fmt.Println("管道已经关闭,准备退出!!")break}fmt.Println("v:", v)}
}

五、goroutine单向管道

一般用于函数参数,比如只读、只写单向管道,看看下面和双向管道有何区别?
生产者:chan<-
消费者:<-chan
双向管道时都是:<-numChan

package main
import ("fmt""time"
)// 生产者:只写入数据
func producer(out chan<- int) {for i := 1; i < 11; i++ {out <- ifmt.Println("写入数据:", i)}close(out)
}// 消费者:只读数据
func consumer(in <-chan int) {for v := range in {fmt.Println("读取数据:", v)}
}func main() {// 创建一个双向通道numChan := make(chan int, 5)// 创建生产者go producer(numChan)// 创建消费者go consumer(numChan)time.Sleep(200)
}

在这里插入图片描述

六、监听管道

在多go程并发时,我们可以通过select进行监听到对应数据,突然觉得类似消息事件一样,一个负责推、一个负责监听…
select:监听多管道 (写入/读写数据、关闭管道)

package main
import ("fmt""time"
)func main() {// 创建两个管道,用来测试监听chan1 := make(chan int)chan2 := make(chan int)// 监听go程go func() {for {select {case data1 := <-chan1:fmt.Println("监听到chan111:", data1)case data2 := <-chan2:fmt.Println("监听到chan222:", data2)default:fmt.Println("正常监听中...")time.Sleep(2 * time.Second)}}}()// go程:两个管道分别写入数据go func() {for i := 0; i < 5; i++ {chan1 <- ii++chan2 <- i}}()count := 1for {time.Sleep(10 * time.Second)if count == 6 {break}count++}
}

如下图,可以看到当我们监听到有写入数据时会得到对应的类型数据,当没有写入时 default 一直在负责监听!
在这里插入图片描述

总结

以上就是今天学习的内容,本文仅仅简单介绍了goroutine的使用,而在项目中如何实践还请大家多多查阅资料了解!

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
函授本科是什么 自考本科还是函... 很多小伙伴在选择学历提升方式的时候,可能会感到很迷茫,不知道报考自考本科还是函授本科,两者有什么区别...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
安徒生童话有哪些 安徒生童话的... 从德国汉堡港乘轮船渡波罗的海抵丹麦王国,就到了安徒生的祖邦。安徒生(1805-1875)以童话作品闻...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...