广告
返回顶部
首页 > 资讯 > 前端开发 > html >Go语言基础并发channel
  • 188
分享到

Go语言基础并发channel

2024-04-02 19:04:59 188人浏览 八月长安
摘要

这篇文章主要讲解了“Go语言基础并发channel”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go语言基础并发channel”吧!为什么需要channel

这篇文章主要讲解了“Go语言基础并发channel”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go语言基础并发channel”吧!

为什么需要channel

channel在Go中,也叫做管道,是用来多线程之间共享数据的。

通常情况下,在Go中共享数据用的也是channel,但是在Go有两种共享数据方式。

  • 共享内存实现通讯。

  • 通过管道(channel)通讯(推荐)。

为啥子共享内存通讯不太推荐?

示例代码:多线程修改一个值。

函数

func Calc() {     defer wg.Done()     NUM = NUM - 1 }

main

var NUM = 100 var wg sync.WaitGroup  func main() {     for i := 0; i<100;i++  {         wg.Add(1)         go Calc() }     wg.Wait()     fmt.Println(NUM) }

执行结果

Go语言基础并发channel

没错,是2,懵了吧,哈哈哈,理论应该是0才对呀。

这是为啥?

这就是共享内存不太推荐的原因,我们的代码已经是多线程了。

在第一个函数代码中,第3行,NUM = NUM - 1。

如果多个线程同时执行到这一行,并且没有加,就会出现数据错乱。

那该怎么做呢?

加锁,加锁可以保证某一段代码只能被一个线程执行,防止被争抢。

代码

func Calc() {     defer wg.Done()     mutex.Lock()     NUM = NUM - 1     mutex.Unlock() }

第3行加锁,第5行解锁。

执行结果

Go语言基础并发channel

这次真的是0的,不管执行几次。

但是会发现一个问题,如果采用这种方式,需要常常注意竞争问题。

所以不是太推荐,需要考虑的比较多,并且各种加锁会消耗性能。

channel语法

channel格式

var 变量名 chan 类型 例如 var x1 chan int //x1管道里面只能存int类型数据 var x2 chan string //x2管道里面只能存字符串类型数据

注意

Go语言基础并发channel

定义管道时,chan int是一个整体,别搞错了各位。

创建channel

创建channel,只能通过make创建。

格式

var 变量名 = make(chan 类型,[管道大小]) 示例 var chan1 = make(chan int,10)//管道可以放10个int元素 var chan2 = make(chan string,5)//管道可以放5个string元素

channel操作

创建一个管道。

ch = make(chan int,10)

channel是一个管道,就像一个管子。

所以可以像管子里面塞东西,并且能取东西,关闭管道就是这个管道不能用了,里面的值取完就打样了。

像管子塞东西(发送)ch <- 666。

从管子取东西(接收)var x = <- ch。

关闭管子close(ch)。

注意:channel是先入先出结构,就像这样。

Go语言基础并发channel 

注意事项:

  • 如果通道塞满了,再塞 会阻塞住。

  • 如果通道关闭了,是不能再塞值了,否则会panic。

  • 即使通道关闭了,依然可以取值,直到将管道的值取完,取完后得到的是对应类型零值。

  • 管道不能重复关闭,重复关闭会panic。

无缓冲管道

无缓冲就是这个管道没有长度,就像这样。

就像快读员没有快递柜,需要直接将快递给客户,如果没人要就撂摊子。

Go语言基础并发channel

示例代码

package main  import (     "fmt" )  //模拟张三 func 张三(x chan string) {     var a = <-x     fmt.Println(a) }  func main() {     //通道没有长度,就是无缓冲通道     var x = make(chan string)     go 张三(x)     x <- "张三的快递"     fmt.Println("张三快递交付成功") }

第16行写入一个值,同理,张三就要等着去接,如果没人接,那就完了。

假设注释第9行代码。

Go语言基础并发channel

直接报错,all goroutines are asleep - deadlock!,这句话的意思是所有的协程都睡着了,死锁

无缓冲说明通道长度为0,发送一个值会阻塞住。

这就相当于快递员直接找张三,但是张三没了,但是快递员还得一直等着,等等等,然后挂了,终究还是没送出去。

有缓冲管道

Go语言基础并发channel

这个就简单啦,多了一个快递柜,快递员直接将快递仍快递柜就行了。

示例代码

package main  import (     "fmt"     "sync" )  var wg sync.WaitGroup  //快递员,快递员放10个快递 func 快递员(kuaidigui chan string) {     defer wg.Done()     for i := 0; i < 10; i++ {         fmt.Println("快递员放入了第",i,"快递")         kuaidigui <- fmt.Sprintf("第%d个快递", i) }     //放完快递就关闭了通道     close(kuaidigui) }  //张三,拿走3个快递 func 张三(kuaidigui chan string) {     defer wg.Done()     for i := 0; i < 3; i++ {         fmt.Println("张三拿走" + <-kuaidigui) } } //李四拿走7个快递 func 李四(kuaidigui chan string) {     defer wg.Done()     for i := 0; i < 7; i++ {         fmt.Println("李四拿走" + <-kuaidigui) } } func main() {     //快递柜,10个大小     var 快递柜 = make(chan string, 10)     wg.Add(3)     go 快递员(快递柜)     go 张三(快递柜)     go 李四(快递柜)     wg.Wait() }

执行结果

Go语言基础并发channel 

遍历channel两种方式

代码

func main() {     //快递柜,10个大小     var ch = make(chan int, 10)     //向管道中发送值     for i := 0; i < 10; i++ {         ch <- i }     //方式一取值     //for {     //i, ok := <-ch     ////取完值ok就是false     //if !ok {     //      //结束循环     //      break     //}     //fmt.Println(i)     //}     //方式二取值     for i:=range ch{         fmt.Println(i) } }

执行结果

Go语言基础并发channel

报错是因为我在main中完成了发送值和取值两个操作,所以会出现上述问题,但是结果是没有错的。

单向通道

我们知道通道是可以发送值和取值的,但是某些场景为了安全起见,理论来说只能取值,后者只能发送值。

单向通道通常只在函数参数中体现。

  • 形参 chan<- chan类型只写。

  • 形参 <-chan chan类型只读。

修改上述快递员代码。

package main  import (     "fmt"     "sync" )  var wg sync.WaitGroup  //快递员,快递员放10个快递,只写 chan<- string func 快递员(kuaidigui chan<- string) {     defer wg.Done()     for i := 0; i < 10; i++ {         fmt.Println("快递员放入了第", i, "快递")         kuaidigui <- fmt.Sprintf("第%d个快递", i) }     //放完快递就关闭了通道     close(kuaidigui) }  //张三,拿走3个快递,只读<-chan string func 张三(kuaidigui <-chan string) {     defer wg.Done()     for i := 0; i < 3; i++ {         fmt.Println("张三拿走" + <-kuaidigui) } }  //李四拿走7个快递 func 李四(kuaidigui <-chan string) {     defer wg.Done()     for i := 0; i < 7; i++ {         fmt.Println("李四拿走" + <-kuaidigui) } } func main() {     //快递柜,10个大小     var 快递柜 = make(chan string, 10)     wg.Add(3)     go 快递员(快递柜)     go 张三(快递柜)     go 李四(快递柜)     wg.Wait() }

总结

上述讲述了Go语言并发如何和channel配合使用,毕竟我们一般的任务都不是单独运行的,都是互相配合的。

感谢各位的阅读,以上就是“Go语言基础并发channel”的内容了,经过本文的学习后,相信大家对Go语言基础并发channel这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: Go语言基础并发channel

本文链接: https://www.lsjlt.com/news/80083.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Go语言基础并发channel
    这篇文章主要讲解了“Go语言基础并发channel”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go语言基础并发channel”吧!为什么需要channel...
    99+
    2022-10-19
  • Go语言并发编程基础上下文概念详解
    目录前言1 Go 中的 Context2 Context 接口3 Context Tree4 创建上下文4.1 上下文创建函数4.2 Context 使用规范4.3 Context ...
    99+
    2022-11-11
  • go语言开发需要什么基础
    go语言开发需要有一定的编程基础、了解面向对象编程的基本原理和概念、熟悉并理解Go语言的基本语法和语法规则、掌握一些Go语言特有的知识和技术、了解Go语言的标准库和常用的第三方库等基础。1、编程基础,对于没有编程经验或者仅了解某种脚本语言的...
    99+
    2023-08-03
  • Go语言CSP并发模型goroutine及channel底层实现原理
    目录Go的CSP并发模型(goroutine + channel)1、goroutinegoroutine的优点:2、channel无缓存channel有缓存channel3、Go并...
    99+
    2022-11-13
  • Go语言基础之指针
    区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针。 要搞明白Go语言中的指针需要先知道3个概念:指针地址、指针类型和指针取值。 Go语言中的指针 任何程序数据载入内存后,在内存都有他们的地址,这就是指针。而为了保存一...
    99+
    2023-08-30
    golang 开发语言 后端
  • 0基础如何学go语言
    0基础学习Go语言需要分阶段进行,从基础知识到实践项目,逐步深入。以下是一个建议的学习路径:1、学习基础知识:了解编程基本概念,如变量、数据类型、运算符、控制结构等。学习Go语言的基本语法,如变量声明、数据类型、运算符、控制结构、函数等。学...
    99+
    2023-10-26
    go语言
  • 零基础学go语言多久
    学习一门编程语言的时间因人而异,特别是对于零基础的学习者来说,学习Go语言所需的时间会有所不同。以下是我对零基础学习Go语言所需时间的详细解答:1、学习基础知识(1-2周):对于零基础的学习者来说,首先需要学习Go语言的基础知识,包括语法、...
    99+
    2023-10-26
    go语言
  • 0基础可以学go语言吗
    0基础可以学Go语言。Go语言(Golang)是一门适合初学者的编程语言,它的语法简洁明了,学习曲线相对较低。对于没有任何编程经验的人来说,只要具备一定的逻辑思维和数学基础,就可以开始学习Go语言。当然,学习任何一门编程语言都需要付出时间和...
    99+
    2023-10-26
    go语言 Golang
  • Go语言基础之Time包详解
    Time包是Go语言中用于处理时间的一个标准库。它提供了一系列函数和类型,用于获取当前时间、时间格式化、时间计算等操作。在Go语言中...
    99+
    2023-08-29
    Go语言
  • Go语言基础知识点介绍
    Go 语言教程 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。 Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thom...
    99+
    2022-11-12
  • go语言如何并发
    这篇文章主要介绍“go语言如何并发”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“go语言如何并发”文章能帮助大家解决问题。Go语言通过编译器运行时(runtime),从语言上支持了并发的特性;并发是...
    99+
    2023-07-05
  • Go语言中的通道channel详情
    目录一、Go语言通道基础概念1.channel产生背景2.channel工作方式二、通道使用语法1.通道的声明与初始化2.将数据放入通道内3.从通道内取出数据4.关闭通道close三...
    99+
    2022-11-13
  • 初探Go语言中的Goroutine和channel
    本篇文章带大家初步了解Go语言中的Goroutine和channel,希望对大家有所帮助!Go 语言的 CSP 并发模型的实现包含两个主要组成部分:一个是 Goroutine,另一个是 channel。本文将会介绍它们的基本用法和注意事项。...
    99+
    2023-05-14
    go语言 Golang
  • Google Go语言基础知识有哪些
    这篇文章主要讲解了“Google Go语言基础知识有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Google Go语言基础知识有哪些”吧!先来个hel...
    99+
    2022-10-19
  • Go语言基础之怎么使用Map
    这篇文章主要讲解了“Go语言基础之怎么使用Map”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go语言基础之怎么使用Map”吧!引入mapmap,在Python中叫字典,Java中也叫map...
    99+
    2023-06-16
  • Go语言基础反射示例详解
    目录概述语法一、基本操作二、修改目标对象三、动态调用方法总结示例 概述 在程序运行期对程序动态的进行访问和修改 reflect godoc: https://golang.org/p...
    99+
    2022-11-12
  • Go语言基础知识点有哪些
    这篇文章主要介绍Go语言基础知识点有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Go 语言教程Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。Go是从2007年末由Robert Gries...
    99+
    2023-06-20
  • 详解go语言的并发
    目录1、启动go语言的协程2、runtime.Goexit()方法。立即终止当前的协程3、runtime.GOMAXPROCS()表示go使用几个cpu执行代码4、管道定义和创...
    99+
    2022-06-07
    详解go语言 GO 并发 go语言
  • Go语言并发编程 sync.Once
    sync.Once用于保证某个动作只被执行一次,可用于单例模式中,比如初始化配置。我们知道init()函数也只会执行一次,不过它是在main()函数之前执行,如果想要在代码执行过程中...
    99+
    2022-11-12
  • Go语言基础go接口用法示例详解
    目录概述语法定义接口实现接口空接口接口的组合总结 概述 Go 语言中的接口就是方法签名的集合,接口只有声明,没有实现,不包含变量。 语法 定义接口 type [接口名] inte...
    99+
    2022-11-12
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作