Go语言的通道

Go语言的箭头语法:让前端更像PHP了! 总结一下,通过引入箭头语法,Go语言在前端开发中更接近于PHP的风格,提供了更直观、易用的字段和方法访问方式。如果你是一个熟悉PHP语言的前端开发者,那么使用箭头语法的Go语言将更加符合你的编程习惯。为了让Go语言在前端开发中更加灵活和便捷,Go社区引入了箭头语法,使其更接近PHP语言的风格。这种语法的引入使得Go语言在前端开发中更加直观和易用,同时也增加了与其他语言的兼容性。通过这个简单的示例,我们可以看到箭头语法的用法非常直观和简洁,使得代码更易读、易懂。在上面的示例代码中,我们定义了一个名为。 阅读详情

《Effective Go》有一句话很好地说明了Go语言的并发实现理念:“不要通过共享内在来通信,而通过通信来共享内存。”

通道的创建语法如下:

c:=make(chan string)

使用内置函数make创建一个通道,这是使用关键字chan指定的。

向通道发送消息的语法如下:

c<="Hello World"

从通道那里接收消息的语法如下:

msg:=<-c

要从通道那里接收消息,需要在<-后面加上通道名。可使用简短变量赋值,将来自通道的消息直接赋给变量。箭头向左表示数据离开通道(接收),箭头向右表示数据进入通道(发送)。

使用通道进行通信,程序清单如下:(代码错误,没搞清楚。)

package main

import(
  "fmt"
  "time"
)
func slowFunc(){
  time.Sleep(time.Second*2)
  c <- "slowFunc() finished"
}
func main(){
  c:=make(chan string)
  go slowFunc()
  msg:=<-c
  fmt.Println(msg)
}

运行结果如下:

# command-line-arguments
./main.go:9:3: undefined: c

让缓冲通道接收两条消息,程序清单如下:

package main

import(
  "fmt"
  "time"
)
func receiver(c chan string){
  for msg:=range c{
    fmt.Println(msg)
  }
}
func main(){
  messages:=make(chan string,2)
  messages<-"hello"
  messages<-"world"
  close(messages)
  fmt.Println("Pushed two messages onto Channel with no receivers")
  time.Sleep(time.Second*1)
  receiver(messages)
}

运行结果如下:

Pushed two messages onto Channel with no receivers
hello
world

通道和流程控制,程序清单如下:

package main

import(
  "fmt"
  "time"
)
func pinger(c chan string){
  t:=time.NewTicker(1*time.Second)
  for{
    c<-"ping"
    <-t.C
  }
}
func main(){
  messages:=make(chan string)
  go pinger(messages)
  msg:=<-messages
  fmt.Println(msg)
}

运行结果如下:

ping

不断地执行指定的操作,程序清单如下:

package main

import(
  "fmt"
  "time"
)
func pinger(c chan string){
  t:=time.NewTicker(1*time.Second)
  for{
    c<-"ping"
    <-t.C
  }
}
func main(){
  messages:=make(chan string)
  go pinger(messages)
  for{
    msg:=<-messages
    fmt.Println(msg)
  }
}

运行结果如下:

不断地出现ping,每一个ping的间隔有一些时间。死循环。

代码如下:

package main

import(
  "fmt"
  "time"
)
func pinger(c chan string){
  t:=time.NewTicker(1*time.Second)
  for{
    c<-"ping"
    <-t.C
  }
}
func main(){
  messages:=make(chan string)
  go pinger(messages)
  for i:=0;i<5;i++{
    msg:=<-messages
    fmt.Println(msg)
  }
}

运行结果如下:(有时间间隔)

ping
ping
ping
ping
ping

select语句,程序清单如下:

package main

import(
  "fmt"
  "time"
)
func ping1(c chan string){
  time.Sleep(time.Second*1)
  c<-"ping on channel1"
}
func ping2(c chan string){
  time.Sleep(time.Second*2)
  c<-"ping on channel2"
}
func main(){
  channel1:=make(chan string)
  channel2:=make(chan string)
  go ping1(channel1)
  go ping2(channel2)
  select{
  case msg1:=<-channel1:
    fmt.Println("received",msg1)
  case msg2:=<-channel2:
    fmt.Println("received",msg2)
  }
}

运行结果如下:

received ping on channel1

代码如下:

package main

import(
  "fmt"
  "time"
)
func ping1(c chan string){
  time.Sleep(time.Second*3)
  c<-"ping on channel1"
}
func ping2(c chan string){
  time.Sleep(time.Second*2)
  c<-"ping on channel2"
}
func main(){
  channel1:=make(chan string)
  channel2:=make(chan string)
  go ping1(channel1)
  go ping2(channel2)
  select{
  case msg1:=<-channel1:
    fmt.Println("received",msg1)
  case msg2:=<-channel2:
    fmt.Println("received",msg2)
  }
}

运行结果如下:

received ping on channel2

给select语句指定超时时间,代码如下:

package main

import(
  "fmt"
  "time"
)
func ping1(c chan string){
  time.Sleep(time.Second*3)
  c<-"ping on channel1"
}
func ping2(c chan string){
  time.Sleep(time.Second*2)
  c<-"ping on channel2"
}
func main(){
  channel1:=make(chan string)
  channel2:=make(chan string)
  go ping1(channel1)
  go ping2(channel2)
  select{
  case msg1:=<-channel1:
    fmt.Println("received",msg1)
  case msg2:=<-channel2:
    fmt.Println("received",msg2)
  case <-time.After(500*time.Millisecond):
    fmt.Println("no message received. giving up.")
  }
}

运行结果如下:

no message received. giving up.

使用退出通道,程序清单如下:

package main

import(
  "fmt"
  "time"
)
func sender(c chan string){
  t:=time.NewTicker(1*time.Second)
  for{
    c<-"I'm sending a message"
    <-t.C
  }
}
func main(){
  messages:=make(chan string)
  stop:=make(chan bool)
  go sender(messages)
  go func(){
    time.Sleep(time.Second*2)
    fmt.Println("Time's up!")
    stop<-true
  }()
  for{
    select{
    case <-stop:
      return
    case msg:=<-messages:
      fmt.Println(msg)
    }
  }
}

运行结果如下:(除了倒数两行,其它都有时间间隔。)

I'm sending a message
I'm sending a message
I'm sending a message
Time's up!

或者:

I'm sending a message
I'm sending a message
Time's up!

通道(channel)——在多个goroutine间通信的管道 

一、通道的特征

二、声明通道类型

声明如下:

var 通道变量 chan 通道类型

通道类型:通道内的数据类型。

通道变量:保存通道的变量。

chan类型的空值是nil,声明后需要配合make后才能使用。

三、创建通道

通道是引用类型,需要使用make进行创建,格式如下:

通道实例:=make(chan 数据类型)

数据类型:通道内传输的元素类型。

通道实例:通过make创建的通道句柄。

四、使用通道发送数据

1、通道发送数据的格式

通道的发送使用特殊的操作符“<-”,将数据通过通道发送的格式为:

通道变量<-值 

通道变量:通过make创建好的通道实例。

值:可以是变量、常量、表达式或者函数返回值等。值的类型必须与ch通道的元素类型一致。

2、通过通道发送数据的例子

使用make创建一个通道后,就可以使用“<-”向通道发送数据。

3、发送将持续阻塞直到数据被接收

把数据往通道中发送时,如果接收方一直都没有接收,那么发送操作将持续阻塞。

五、使用通道接收数据

1、阻塞接收数据

格式如下:

data:=<-ch

2、非阻塞接收数据

格式如下:

data,ok:=<-ch

data:表示接收到的数据。未接收到数据时,data为通道类型的零值。

ok:表示是否接收到数据。

3、接收任意数据,忽略接收的数据

格式如下:

<-ch

代码如下:

package main

import (
	"fmt"
)

func main() {
	//构建一个通道
	ch := make(chan int)
	//开启一个并发匿名函数
	go func() {
		fmt.Println("start goroutine")
		//通过通道通知main的goroutine
		ch <- 0
		fmt.Println("exit goroutine")
	}()
	fmt.Println("wait goroutine")
	//等待匿名goroutine
	<-ch
	fmt.Println("all done")
}

运行结果如下:

wait goroutine
start goroutine
exit goroutine
all done

4、循环接收

代码如下:

package main

import (
	"fmt"
	"time"
)

func main() {
	//构建一个通道
	ch := make(chan int)
	//开启一个并发匿名函数
	go func() {
		//从3循环到0
		for i := 3; i >= 0; i-- {
			//发送3到0之间的数值
			ch <- i
			//每次发送完时等待
			time.Sleep(time.Second)
		}
	}()
	//遍历接收通道数据
	for data := range ch {
		//打印通道数据
		fmt.Println(data)
		//当遇到数据0时,退出接收循环
		if data == 0 {
			break
		}
	}
}

运行结果如下:

3
2
1
0

六、示例:并发打印

代码如下:

package main

import (
	"fmt"
)

func printer(c chan int) {
	//开始无限循环等待数据
	for {
		//从channel中获取一个数据
		data := <-c
		//将0视为数据结束
		if data == 0 {
			break
		}
		//打印数据
		fmt.Println(data)
	}
	//通知main已经结束循环(我搞定了!)
	c <- 0
}

func main() {
	//创建一个channel
	c := make(chan int)
	//并发执行printer,传入channel
	go printer(c)

	for i := 1; i <= 10; i++ {
		//将数据通过channel投送给printer
		c <- i
	}
	//通知并发的printer结束循环(没数据啦!)
	c <- 0
	//等待printer结束(搞定咕我!)
	<-c
}

运行结果如下:

1
2
3
4
5
6
7
8
9
10

七、单向通道——通道中的单行道

1、单向通道的声明格式

只能发送的通道类型为chan<-,只能接收的通道类型为<-chan,格式如下

var 通道实例 chan<- 元素类型       

var 通道实例 <-chan 元素类型

元素类型:通道包含的元素类型

通道实例:声明的通道变量。

2、单向通道的使用例子

3、time包中的单向通道

time包中的计时器会返回一个timer实例,代码如下:

timer:=time.NewTimer(time.Second)

八、带缓冲的通道

1、创建带缓冲的通道

通道实例:=make(chan 通道实例,缓冲大小)

通道类型:和无缓冲通道用法一致,影响通道发送和接收的数据类型。

缓冲大小:决定通道最多可以保存的元素数量。

通道实例:被创建出的通道实例。

代码如下:

package main

import (
	"fmt"
)

func main() {
	//创建一个3个元素缓冲大小的整型通道
	ch := make(chan int, 3)
	//查看当前通道的大小
	fmt.Println(len(ch))
	//发送3个整形元素的通道
	ch <- 1
	ch <- 2
	ch <- 3
	//查看当前通道的大小
	fmt.Println(len(ch))
}

运行结果如下:

PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go> go run main.go
0
3

2、阻塞条件

(1)带缓冲通道被填满时,尝试再次发送数据时发生阻塞。

(2)带缓冲通道为空时,尝试接收数据 时发生阻塞。

九、通道的多路复用——同时处理接收和发送多个通道的数据

select{

        case 操作1:

                响应操作1

        case 操作2:

                响应操作2

        ……

        default:

                没有操作情况

}

十、示例:模拟远程过程调用(RPC)

代码如下:

package main

import (
	"errors"
	"fmt"
	"time"
)

// 模拟RPC客户端的请求和接收消息封装
func RPCClient(ch chan string, req string) (string, error) {

	// 向服务器发送请求
	ch <- req

	// 等待服务器返回
	select {
	case ack := <-ch: // 接收到服务器返回数据
		return ack, nil
	case <-time.After(time.Second): // 超时
		return "", errors.New("Time out")
	}
}

// 模拟RPC服务器端接收客户端请求和回应
func RPCServer(ch chan string) {
	for {
		// 接收客户端请求
		data := <-ch

		// 打印接收到的数据
		fmt.Println("server received:", data)

		// 反馈给客户端收到
		ch <- "roger"
	}
}

func main() {

	// 创建一个无缓冲字符串通道
	ch := make(chan string)

	// 并发执行服务器逻辑
	go RPCServer(ch)

	// 客户端请求数据和接收数据
	recv, err := RPCClient(ch, "hi")
	if err != nil {
		// 发生错误打印
		fmt.Println(err)
	} else {
		// 正常接收到数据
		fmt.Println("client received", recv)
	}

}

运行结果如下:

[Running] go run "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go\main.go"
server received: hi
client received roger

[Done] exited with code=0 in 2.429 seconds

十一、示例:使用通道响应计时器的事件

1、一段时间之后 (time.After)

代码如下:

package main

import (
	"fmt"
	"time"
)

func main() {
	// 声明一个退出用的通道
	exit := make(chan int)

	// 打印开始
	fmt.Println("start")

	// 过1秒后,调用匿名函数
	time.AfterFunc(time.Second, func() {

		// 1秒后,打印结果
		fmt.Println("one second after")

		// 通知main的goroutine已经结束
		exit <- 0
	})

	// 等待结束
	<-exit
}

运行结果如下:

[Running] go run "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go\main.go"
start
one second after

[Done] exited with code=0 in 2.205 seconds

2、定点计时

代码如下:

package main

import (
	"fmt"
	"time"
)

func main() {

	// 创建一个断续器,每500毫秒触发一次
	ticker := time.NewTicker(time.Millisecond * 500)

	// 创建一个计时器,2秒后触发
	stopper := time.NewTimer(time.Second * 2)

	// 声明计数变量
	var i int

	// 不断的检查通道情况
	for {

		// 多路复用通道
		select {
		case <-stopper.C: // 计时器到时了

			fmt.Println("stop")

			// 跳出循环
			goto StopHere

		case <-ticker.C: // 断续器触发了
			// 记录触发了多少次
			i++
			fmt.Println("tick", i)
		}
	}

	// 退出的标签,使用goto跳转
StopHere:
	fmt.Println("done")

}

运行结果如下:

[Running] go run "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go\main.go"
tick 1
tick 2
tick 3
tick 4
stop
done

[Done] exited with code=0 in 5.162 seconds

十二、关闭通道后继续使用通道

1、格式

使用close()来关闭一个通道:

close(ch)

2、给被关闭通道发送数据将会触发panic

代码如下:

package main

import (
	"fmt"
)

func main() {

	// 创建一个整型的胶片
	ch := make(chan int)

	//关闭通道
	close(ch)

	//打印通道的指针,容量和长度
	fmt.Printf("ptr:%p cap:%d len:%d\n", ch, cap(ch), len(ch))

	//给关闭的通道发送数据
	ch <- 1

}

运行结果如下:

[Running] go run "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go\main.go"
ptr:0xc000086060 cap:0 len:0
panic: send on closed channel

goroutine 1 [running]:
main.main()
	c:/Users/a-xiaobodou/OneDrive - Microsoft/Projects/Go/main.go:19 +0x105
exit status 2

[Done] exited with code=1 in 1.243 seconds

3、从已关闭的通道接收数据时将不会发生阻塞

代码如下:

package main

import "fmt"

func main() {
	// 创建一个整形带2个缓冲的通道
	ch := make(chan int, 2)

	// 给通道放入两个数据
	ch <- 0
	ch <- 1

	// 关闭缓冲
	close(ch)

	// 遍历缓冲所有数据,且多遍历1个
	for i := 0; i < cap(ch)+1; i++ {

		// 从通道中取出数据
		v, ok := <-ch

		// 打印取出数据的状态
		fmt.Println(v, ok)
	}
}

运行结果如下:

[Running] go run "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\Go\main.go"
tick 1
tick 2
tick 3
tick 4
stop
done

[Done] exited with code=0 in 5.162 seconds

示例:Telnet回音服务器——TCP服务器的基本结构

同步——保证并发环境下数据访问的正确性

一张图讲透银行个人外汇业务逻辑和实操 个人外汇业务主要分为结售汇和外币兑换两类,前者满足日常跨境需求,后者因投机属性多数银行已暂停。业务核心是利用汇率波动实现货币兑换,满足支付或投资需求。交易涉及客户分类、主流币种、多种渠道和汇率计算规则,需区分直接/间接标价法判断汇率走势。银行通过"货币兑换"科目核算损益,采用期末折算确认盈亏。监管要求包括5万美元年度额度、合法渠道、真实性原则及大额申报等。随着跨境金融数字化发展,掌握基础逻辑和合规要求是安全参与外汇业务的关键。 阅读详情

相关推荐

各种AI的调试日记——辅助工作篇

记录使用各种AI(语言大模型)的心得和总结

m0_73056986的博客 1390

Go语言基础结构 —— Channel 通道

在Go语言中,channel(通道)是一种用于在goroutine之间进行通信和同步的特殊数据结构。它可以看作是一条管道,可以在不同的goroutine之间传递数据。使用通道,你可以在goroutine之间发送和接收值。通道提供了一种安全、同步的方式来共享数据。它确保在发送操作完成之前,接收操作会一直等待,并且在接收操作完成之前,发送操作也会一直等待。这种同步机制可以有效地避免并发访问共享数据时出现的竞争条件和数据竞争。Golang并发的核心哲学是不要通过共享内存进行通信。

xjx的博客 2475

一文入门Qwen-Agent【附实战代码】

Qwen-Agent 是一个开源框架,用于开发基于 Qwen 模型的 AI 智能体应用,一文带你入门使用

m0_55303420的博客 1873

Go 并发之channel(通道)

通道类型的值本身就是并发安全的,这也是 Go 语言自带的、唯一一个可以满足并发安全性的类型。它使用起来十分简单。在声明并初始化一个通道的时候,需要用到 Go 语言的内建函数make。就像用make初始化切片那样,传给这个函数的第一个参数是代表了通道的具体类型的类型字面量。在声明一个通道类型变量的时候,首先要确定该通道类型的元素类型,这决定了可以通过这个通道传递什么类型的数据。比如,类型字面量chan int,其中的chan是表示通道类型的关键字,而int则说明了该通道类型的元素类型。

天天新知 4760

Flowable第一篇、快速上手(Flowable安装、配置、集成)

Flowable是一个轻量级、高效可扩展的工作流和业务流程管理(BPM)引擎,支持在Java应用程序中实现复杂的工作流自动化。Flowable最初是作为Activiti项目的一个分支发展而来的,但它现在已经成为一个独立的开源项目,并在企业级应用中得到了广泛使用

Du_XiaoNan的博客 1万+

iSLIP算法实战:如何用Python模拟交换机优先级匹配(附完整代码)

本文详细介绍了如何使用Python实现iSLIP算法,模拟交换机优先级匹配过程。通过核心的指针滑动逻辑和迭代循环策略,构建了一个完整的iSLIP算法模拟器,并加入可视化模块以直观展示匹配过程。文章还提供了完整的代码框架和性能优化建议,适合网络工程师和Python开发者直接集成到测试环境中。

weixin_29313239的博客 249

Go中的通道

以上就是包含了channel中大部分的重要知识,这些知识是底层中需要具备的能力,所以需要我们进行磨练,对于所有的知识进行回顾,这样对于我们在后面的学习中可能会有更好的帮助,所以要注意其中的重要问题。

z3551906947的博客 757

Linux与Windows双系统,安装完linux后无法通过grub进入Windows的解决方法

先装Windows 10,Windows可正常启动,再装Kali,Kali提示装grub后照装。然而装完后重启发现无Windows选项。

sakurashockwave的博客 6454

Go语言中的通道(Channel)详解

通道是一种可以用来在不同的goroutine之间传递数据的管道。通过通道,一个goroutine可以发送数据给另一个goroutine,而后者则可以从通道接收这些数据。这为Go程序提供了一个非常直接的通信方式,使得开发者能够轻松地构建高并发的应用程序。

songchaoyang123的专栏 1万+

tcmalloc(高并发内存池)简化版讲解-项目

高清发不上去,私我发高清,项目完整代码@我。

2201_75352618的博客 910

手把手教你学PCIE(1.38)--基本概念:ATU(地址转换单元)

ATU(Address Translation Unit)是一种硬件单元,用于在PCIe系统中进行地址转换。它将设备的本地地址(外部地址)转换为系统内存或配置空间中的全局地址(内部地址),反之亦然。ATU的工作原理:通过地址匹配和转换,确保事务能够在不同的地址空间之间正确路由。配置寄存器:通过配置寄存器来设置地址转换规则。应用场景:地址空间隔离、访问控制、动态地址管理、虚拟化和多租户。

MHD0815的博客 2054

go语言通道插入0_golang go语言通道类型的通道示例 通道的通道

几点注意:go的无缓存通道通道make 创建后,即使里面是空的,也可以取里面内容。但是程序会被阻塞。通道的规则是没人取,是不能往里面放的。放的线程会阻塞。最外层的requestChan相当于一个总线或媒介。生产者goroutineD直接从requestChan通道里面再取一个内部通道responseChan,这时不管responseChan创建没有,如果没有的话会阻塞,直到取到后,往respons...

weixin_36176546的博客 147

openclaw 保姆级部署与核心玩法解析:国产DeepSeek模型 + 飞书

OpenClaw是一款功能强大的开源AI个人助理,支持全平台私有化部署,数据完全本地掌控。它不仅可通过聊天窗口直接操控电脑(安装软件、创建项目),还支持接入飞书等主流通讯工具,化身24小时在线的智能助理。本文提供了从零开始的详细部署教程,涵盖基础安装、模型配置(如GLM-4、DeepSeek)到飞书集成的完整实战指南,助你将这款“核动力”AI助手快速融入日常工作流。

甘蓝的专栏 2997

go语言通道插入0_golang通道定义

一. 通道的定义先上一段代码,func main() {// 示例1//通道是一个先进先出(FIFO)的队列channel := make(chan int,3)channel channel channel fmt.Printf("the first channel value is %v\n",v := fmt.Printf("the first channel value is %v\n"...

weixin_32691939的博客 201

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

go语言通道插入0_Golang通道Channel详解

通道类型是Go自带的,相当于是一个先进先出的队列,同时唯一一个可以满足并发安全性的类型。声明一个通道类型变量的时候,首先需要确定通道类型的元素类型,然后还要确定通道的容量,当然默认容量是0。初始化使用make进行初始化,如下所示:c := make(chan int)c := make(chan string, 10)如果不指定容量,默认通道的容量是0,这种通道也成为非缓冲通道。通道的发送和接收特...

weixin_28927927的博客 411

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Go语言自学系列 | golang并发变成之通道channel

视频来源:B站《golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]》 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,请移步至知乎网站,谢谢支持! 附上汇总贴:Go语言自学系列 | 汇总 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/484035621 Go提供了一种称为通道的机制,用于在goroutine之间共享数据。当您作为goroutine执行并发活动时,需要在goroutine之间共享资源或数据,通道

团爸讲算法 497

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

golang go语言通道类型的通道示例 通道的通道

几点注意:go的无缓存通道 通道make 创建后,即使里面是空的,也可以取里面内容。但是程序会被阻塞。 通道的规则是没人取,是不能往里面放的。放的线程会阻塞。   最外层的requestChan相当于一个总线或媒介。 生产者goroutineD直接从requestChan通道里面再取一个内部通道responseChan,这时不管responseChan创建没有,如果没有的话会阻塞,直到取...

weixin_34208185的博客 273

Go语言 通道

说说 Go语言 的通道~

qq_19018277的博客 713

Go语言通道

函数单纯并发执行是没有意义的,函数与函数之间交换数据才可以体现并发执行函数的意义,其中Go语言的并发模型是csp模型,提倡通过通信共享内存而不是通过共享内存而实现通信,共享内存实现通信在不同的goroutine中容易发生竞态的问题,为了保证数据交换的正确性,必须使用互斥量对内存进行加锁,但是这种做法会造成性能上的一些问题。在go语言中,goroutine是go程序并发的执行体,go语言为goroutine之间提供了一个通信的桥梁:channel,也即goroutine之间的连接,channel是让一个gor

二哈 823

Go语言协程通道使用问题

总之,虽然 select 和 time.After 的模式简单直接,但在需要真正取消操作或在多个 goroutine 间协调的场景中,使用 context 包是更好的选择。在使用 context 的版本中,如果超时发生,操作会被主动取消,避免了资源浪费。Context 包的引入大大简化了在 Go 程序中处理取消、超时和跨调用边界传值的复杂性,是构建健壮的并发和分布式系统的重要工具。是实现优雅取消和超时处理的关键机制,它允许 Go 程序以非阻塞的方式响应取消信号,从而编写出更加健壮和响应式的并发代码。

2301_76723322的博客 1807

Go语言关闭通道后继续使用通道

通达是一个引用,和map类似。map在没有任何外部引用时,Go语言程序在运行时(runtime)会自动对内存进行垃圾回收(Garbage Collection,GC)。类似的,通道也可以被垃圾回收,但通道也可以被主动关闭。 格式 使用close()来关闭一个通道: close(ch) 关闭的通道依然可以被访问,访问被关闭的通道将会发生一些问题。 给被关闭通道发送数据将会触发pani...

zuiyijiangnan的博客 1566

go语言通道插入0_Go 语言通道

51Reboot 运维开发Golang 课程K8S 课程Python 自动化进阶课程Python 基础实战课程运维前端课程课程试听预约请扫码>>> 一 两种并发模型多线程共享内存,以共享内存的方式来通信。比如 java 在访问共享数据的时候,通过加锁来实现,java.util.concurrent包。CSP(communicating sequential proces...

weixin_42443533的博客 160

go语言通道插入0_Go语言之通道

上一篇我们讲的原子函数和互斥锁,都可以保证共享数据的读写。但是呢,它们还是有点复杂,而且影响性能。对此,Go又为我们提供了一种工具,这就是通道。所以在多个goroutine并发中,我们不仅可以通过原子函数和互斥锁保证对共享资源的安全访问,消除竞争的状态,还可以通过使用通道,在多个goroutine发送和接受共享的数据,达到数据同步的目的。通道,它有点像在两个routine之间架设的管道:一个gor...

weixin_32815027的博客 251

【Golang】✔️走进 Go 语言✔️ 第十六课 协程 & 通道

【Golang】✔️走进 Go 语言✔️ 第十六课 协程 & 通道.

我是小白呀的博客 1709

理解Go语言中的通道

介绍Go语言中的通道

禅与代码的艺术 623

深入理解 Go 语言中的通道的通道

本文深入解析Go语言中的"通道的通道"这一高级并发编程技术。通道的通道(chan chan T)指元素类型为通道的通道,它提供了更灵活的通信机制。文章通过代码示例展示了基本用法,并给出了任务分发系统的实际应用场景:利用通道的通道动态管理工作协程,实现任务分配和结果收集。这种技术具有灵活性强、可扩展性高等优势,但也需注意内存管理和通道关闭问题。掌握通道的通道有助于开发复杂高效的并发程序,是Go语言并发编程的重要进阶技能。

Tekin 是深耕技术 20 年的全栈实战派专家,精通 Go/Python/Java 等多语言开发。博客专注技术原理与实战结合,深度解析 Python 高阶编程、Go 语言架构、数据库优化等硬核内容。涵盖并发编程、机器学习、云原生等前沿领域,通过真实案例拆 1289
上一篇: Go语言的使用Goroutine
下一篇: Go语言的使用包实现代码重用
DXB2021
博客等级 码龄5年 307粉丝 289原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值