当前位置: 首页 > wzjs >正文

平面设计接单价格表北京seo报价

平面设计接单价格表,北京seo报价,wordpress获取分类目录,公司网站设计制作开发方案Go 语言中的 channel 是基于 CSP(Communicating Sequential Processes)思想实现的通信机制。其核心理念是: 通过通信共享内存,而不是通过共享内存通信 也就是说,应当让不同 goroutine 之间通过传递数据来共享状态&…

Go 语言中的 channel 是基于 CSP(Communicating Sequential Processes)思想实现的通信机制。其核心理念是:

  • 通过通信共享内存,而不是通过共享内存通信
    也就是说,应当让不同 goroutine 之间通过传递数据来共享状态,避免直接共享内存而产生竞态问题。

  • FIFO 队列
    Channel 本身就是一个队列,按照先进先出的原则传递数据。

  • 阻塞与死锁

    • 无缓冲通道:发送操作和接收操作必须同时发生,否则将阻塞,容易发生死锁。
    • 有缓冲通道:有固定的缓冲区,当缓冲区满时发送操作阻塞;当缓冲区空时接收操作阻塞。
  • 数据类型限制
    每个 channel 只能存放同一种数据类型,且 channel 是引用类型,需要通过 make 进行初始化。

  • 同步通信与协程控制
    Channel 不仅用于数据传递,还可以用来实现不同 goroutine 之间的同步控制,比如等待子协程执行完毕再退出主协程。

  • 多路复用
    使用 select 语句可以同时监听多个 channel 的操作,实现非阻塞通信和超时控制。

1. 无缓冲通道的基本使用

知识点说明:

  • 无缓冲通道没有存储空间,发送和接收必须成对出现。当一方操作时,另一方必须就绪,否则就会阻塞。
  • 该示例展示了如何在一个 goroutine 中发送数据,通过主 goroutine 接收数据。

代码示例:

// 文件名: 03channel_unbuffered.go
package mainimport ("fmt""time"
)// 发送数据到无缓冲通道
func senddata(ch chan int) {ch <- 1fmt.Println("往通道里存放数据 1")ch <- 2fmt.Println("往通道里存放数据 2")
}func main() {// 创建无缓冲通道(容量为0)ch1 := make(chan int)// 启动一个 goroutine 发送数据到通道go senddata(ch1)// 主 goroutine 休眠一段时间以等待子协程发送数据time.Sleep(3 * time.Second)// 按照先进先出的顺序接收数据data := <-ch1fmt.Println("拿到通道数据:", data)data2 := <-ch1fmt.Println("拿到通道数据:", data2)// 若再接收数据,由于通道中没有数据,将会阻塞// data3 := <-ch1// fmt.Println("第三次拿到通道数据:", data3)
}

2. 利用无缓冲通道实现协程同步

知识点说明:

  • 协程同步:在 Go 中,主协程退出会导致整个程序结束。如果想等待子协程执行完毕,可以利用无缓冲通道作为信号量。
  • 使用空结构体(struct{})作为信号传递,因为它不占用内存空间。

代码示例:

// 文件名: 03channel_sync.go
package mainimport ("fmt""time"
)// 定义空结构体,作为信号传递
type none struct{}// 发送信号到无缓冲通道,模拟子协程任务完成
func senddata(ch chan none) {fmt.Println("this is senddata")time.Sleep(2 * time.Second)ch <- none{} // 发送一个空结构体信号
}func main() {fmt.Println("start....")// 创建无缓冲通道(类型为 none)ch1 := make(chan none)// 启动子协程执行任务go senddata(ch1)// 主协程等待接收到信号后再继续<-ch1fmt.Println("end....")
}

3. 通道的关闭与数据消费

知识点说明:

  • 通道关闭:发送方完成数据发送后,通过 close(ch) 关闭通道,可以防止消费者无限等待数据。
  • 数据消费:接收方可以通过三种方式判断通道是否关闭:
    1. 判断读取到的值是否为数据类型的零值;
    2. 使用 value, ok := <-ch 判断;
    3. 使用 range 自动遍历,直到通道关闭。

代码示例:

// 文件名: 03channel_close.go
package mainimport ("fmt"
)// 发送数据并关闭通道
func sendata(ch chan string) {for i := 0; i < 3; i++ {ch <- fmt.Sprintf("发送数据%d", i)}// 打印提示并关闭通道,确保接收方不会因无数据而死锁defer fmt.Println("发送数据完毕")defer close(ch)
}func main() {ch1 := make(chan string)go sendata(ch1)// 方式1:读取数据后判断零值(适用于数据类型零值不会作为有效数据的情况)/*for {data := <-ch1if data == "" { // 字符串的零值为 ""break}fmt.Println("从通道中获取到的数据:", data)}*/// 方式2:使用 value, ok 判断通道是否关闭/*for {data, ok := <-ch1if !ok {break}fmt.Println("2从通道中获取到的数据:", data)}*/// 方式3:使用 range 遍历通道(推荐方式)for value := range ch1 {fmt.Println("3从通道中获取到的数据:", value)}
}

4. 有缓冲通道的使用

知识点说明:

  • 有缓冲通道:在创建通道时指定缓冲区大小,允许发送者先存储一定数量的数据而不必等待接收者。
  • 当缓冲区满时,发送操作将阻塞;当缓冲区空时,接收操作将阻塞。
  • 适用于生产者和消费者速度不一致的场景。

代码示例:

// 文件名: 03channel_buffered.go
package mainimport ("fmt""time"
)// 向有缓冲通道发送数据
func senddata(ch chan string) {for i := 0; i <= 10; i++ {ch <- fmt.Sprintf("放入数据%d", i)fmt.Printf("往通道放入数据%d\n", i)}// 发送完成后关闭通道defer close(ch)
}func main() {// 创建一个带缓冲的通道,缓冲区大小为 6ch1 := make(chan string, 6)go senddata(ch1)// 等待一定时间,保证数据发送到缓冲区time.Sleep(2 * time.Second)// 使用 range 循环读取数据,直到通道关闭for v := range ch1 {fmt.Println("读取通道数据:", v)}
}

5. 使用 select 监听多个通道

知识点说明:

  • select 语句:允许同时监听多个通道操作,当其中一个通道操作准备就绪时执行对应的 case;若多个同时就绪,则随机选择。
  • 超时控制:结合 time.After 实现超时等待,避免长时间阻塞。
  • default 分支:用于非阻塞检测,如果没有通道操作准备好,则执行 default 分支。

代码示例:

// 文件名: 03channel_select.go
package mainimport ("fmt""time"
)func main() {ch1 := make(chan int)ch2 := make(chan int)ch3 := make(chan int)// 分别启动三个 goroutine,在不同时间发送数据到各自的通道go func() {time.Sleep(10 * time.Second)ch1 <- 1}()go func() {time.Sleep(2 * time.Second)ch2 <- 2}()go func() {time.Sleep(3 * time.Second)ch3 <- 3}()// 循环监听 3 次 select 中的不同通道或超时/default 分支for i := 0; i < 3; i++ {select {case msg := <-ch1:fmt.Println("接收到数据 from ch1:", msg)case msg := <-ch2:fmt.Println("接收到数据 from ch2:", msg)case msg := <-ch3:fmt.Println("接收到数据 from ch3:", msg)// 超时控制case <-time.After(1 * time.Second):fmt.Println("设置超时时间!timeout")// 非阻塞操作default:fmt.Println("没有消息准备好")}}
}

总结

本次整理中,我们按照以下知识点对 channel 的使用进行了归类整理:

  1. 无缓冲通道的基本使用:展示了发送和接收操作必须同步进行的特性。
  2. 利用无缓冲通道实现协程同步:通过空结构体信号,让主协程等待子协程执行完毕。
  3. 通道的关闭与数据消费:演示了如何关闭通道以及用 range 自动遍历数据,避免因死锁而阻塞。
  4. 有缓冲通道的使用:展示了带缓冲区通道在生产者与消费者场景中的使用,以及缓冲满、缓冲空时的阻塞机制。
  5. select 监听多个通道:通过 select 实现多路复用、超时控制以及非阻塞检测。
http://www.dtcms.com/wzjs/75001.html

相关文章:

  • wordpress 显示pdf插件自媒体seo优化
  • 做网站最简单企业网站制作方案
  • 网站开发助理是做什么的网络营销策划方案怎么做
  • 优质网站建设哪家好网页设计作品
  • 大连有什么好玩的地方安徽搜索引擎优化
  • 全球军事新闻网站免费的网络推广渠道
  • 营销网站建设的因素互联网广告代理可靠吗
  • 韩城网站建设爱站网站
  • 高级网站开发工程师证网站快速优化排名排名
  • 安庆注册公司广州seo排名外包
  • wordpress类目urlaso优化{ }贴吧
  • 成都网站建设新线加中国站长工具
  • 公众号文案里怎么做网站链接软文营销策划方案
  • 一站式建设网店运营公司
  • 做网站的平台有哪些网页在线代理翻墙
  • 网站扫码怎么做昆山网站建设推广
  • 怎么做网站销售站长之家关键词挖掘
  • 苏州网站营销公司墨猴seo排名公司
  • 变身小说网址wordpress郑州seo技术服务
  • 新媒体营销的发展趋势自然搜索优化
  • ps做网站设计稿热搜榜百度一下你就知道
  • 铜山区建设局局网站上海优化关键词的公司
  • 视频网站怎么搭建免费培训机构管理系统
  • 温州seo全网营销宁波做seo推广企业
  • 霸气又聚财的公司名称泰州seo
  • 做网站后台需要写代码吗杭州搜索引擎排名
  • 放在主机上的网站程序如何建压缩包然后直接下载完整的社群营销方案
  • 高校网站建设滞后推广普通话手抄报句子
  • 高端网站建设 磐石网络专注百度搜索推广收费标准
  • 织梦 图片网站源码怎么创建一个网址