Go语言那些事儿之浅谈协程并发竞争资源问题

举报
Regan Yue 发表于 2021/08/19 13:48:39 2021/08/19
【摘要】 Go语言那些事儿之浅谈协程并发竞争资源问题我们在实际操作过程中,往往会遇到拥有多条协程并发的情况,那么当多条协程并发时,协程之间是如何竞争有限的资源的呢?本文将介绍有关内容。我们先看一看本文实例代码的主函数,两条子协程,主协程3秒后结束。func main() { go fun1() go fun2() time.Sleep(3 * time.Second)}再看看看两条子协程分别是干些什...

Go语言那些事儿之浅谈协程并发竞争资源问题

我们在实际操作过程中,往往会遇到拥有多条协程并发的情况,那么当多条协程并发时,协程之间是如何竞争有限的资源的呢?本文将介绍有关内容。

我们先看一看本文实例代码的主函数,两条子协程,主协程3秒后结束。

func main() {
	go fun1()
	go fun2()

	time.Sleep(3 * time.Second)
}

再看看看两条子协程分别是干些什么吧!

func fun1(){
	//遍历字符串的每一个字符
	for _,c:=range "就像老鼠爱大米"{
		//如果这里使用Println的话,输出的会是字符在字符集中的编号。
		//这里f是format也就是格式的意思。
		fmt.Printf("%c\n",c)
		//runtime.Goexit()
		//每隔一纳秒打印一个字。
		time.Sleep(time.Nanosecond)
	}

}

func fun2(){
	for _,c := range"ReganYue"{
		fmt.Printf("%c\n",c)
		//runtime.Goexit()
		time.Sleep(time.Nanosecond)

	}
}

fun1函数,是遍历输出"就像老鼠爱大米",值得注意的是,这里使用for…range循环遍历字符串的话,不能使用fmt.Println,因为如果这里使用Println的话,输出的会是字符在字符集中的编号。

fmt.Printf 这里f是format也就是格式化的意思。

看看运行结果

R
就
像
e
g
老
鼠
a
n
爱
Y
大
米
u
e

发现两条协程运行的结果均匀分布。这就说明两条协程公平竞争资源,两条协程之间实力旗鼓相当。

可如果激活fun1内的runtime.Goexit()

那么输出结果就是:

R
e
g
a
n
Y
u
e

如果激活fun2内的runtime.Goexit()

那么输出结果就是:

R
像
老
鼠
爱
大
米

因为Goexit杀掉它的 goroutine,其他 goroutine 也不会受到影响。所以当fun1的所在的子协程被杀死时,不会影响fun2所在的子协程的正常运行。

如果本段代码中两个runtime.Goexit()都激活,那么两条协程都只会输出一个字符。

R

因为两条协程在输出完一个字符后就被杀死了。

如果两个及以上个协程在没有同步的情形下去访问共享的资源,并且尝试同一时间读和写共享的资源。就会出现资源竞争问题。出现的这个问题能够让程序变得稍微复杂,本文就暂时不讨论这些复杂情况,想知道的可以关注博主,博主后期会介绍。

我们也可以使用 go build-race 参数,使用它可以了解是否存在资源竞争问题,关于 go build-race 参数的使用,本篇博文暂不介绍,后期博主会尽量详细介绍。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。