channel的使用

1. 运行环境

2. 问题描述?

请教大家一个问题,我看有的程序开头定义一个管道ch := make(chan struct{});然后在结尾处写一个 <-ch;这是起什么作用呢?为了不让程序退出吗?
//: <> (代码问题的话,请提供一份最短的,可复现代码。或相关代码。)

3. 您期望得到的结果?

4. 您实际得到的结果?

讨论数量: 4

GPT 回答

在 Go 语言中,chan struct{} 是一个无缓冲的通道(unbuffered channel)。定义一个通道 ch := make(chan struct{}) 之后,<-ch 的作用是阻塞程序,直到从通道 ch 中接收到一个值为止。

这种技巧常用于在程序的结尾处等待某些事件发生,以防止程序过早退出。由于无缓冲通道在没有发送方的情况下会阻塞接收操作,所以 <-ch 语句将导致程序在此处等待,直到其他地方的代码向通道 ch 发送一个值。

在某些情况下,这种技巧可以用于保持程序的主线程活跃,以等待其他并发任务的完成。当其他任务完成时,可以通过向通道 ch 发送一个值来触发 <-ch 语句的解除阻塞,从而继续执行后续的清理操作或退出程序。

下面是一个简单的示例,演示了使用通道 ch 等待其他任务完成的情况:

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan struct{})

    go func() {
        // 模拟一些耗时的操作
        time.Sleep(2 * time.Second)

        // 任务完成后向通道发送一个值
        ch <- struct{}{}
    }()

    fmt.Println("等待任务完成...")
    <-ch
    fmt.Println("任务已完成,程序退出。")
}
10个月前 评论

简单例子

举个例子,丰巢快递柜子:

  • 你有一个快递 == ch := make(chan int, 1),这个快递可以是一台电脑,一本书,而int则表示你快递的类型,当然,你可以往里面塞任意类型的东西。
  • 快递员塞快递到柜子里去 == ch <- 1
  • 你取快递不用 == <-ch 或者取回拆开用 == a := <- ch

加点难度

丰巢总不会只有一个柜子吧,假如这里有三个柜子:

  • 三个柜子 == ch := make(chan int, 3)
  • 你有四个快递,但是你一次性只能拿走3个,这时候多一个快递则会阻塞住你拿快递的事件(你需要拿完四个才算把拿快递这一事件完成),程序也会阻塞住
    for i := 0, i <= 4; i++ {
      ch <- i
    }

注意的地方

  • 拿完快递之后记得关好门 == close(ch)就是把通道关闭,免得造成资源的浪费
  • 四个柜子满了就不能再塞了,需要你取掉才能塞,但是要注意顺序(先进先出
  • 就像夜宵喝酒一样,我举了个白旗不能喝了,再逼我喝就得翻脸 == panic(),不过怕回家老婆看见可以吐出来 == <- ch 也就是说,通道一经关闭就不能塞数据进去了,不过是可以取出来(限于有缓存的通道)
  • 无缓存通道与有缓存通道区别在于:签收快递是否当面还是存放丰巢柜子;也就是说无缓存通道: :rage:我给了你你就得拿掉。有缓存通道是:我给你塞柜子里你不一定立马去拿。 :yum:

10个月前 评论

channel make的时候分为 阻塞和不阻塞。

<-ch 表示接收到了管道中的信息。如果一直没有接收到 则程序会阻塞在这里(前提是make(chan struct{}),而不是make(chan struct{},1))

当然 楼上的Chapgpt解释的更全面

10个月前 评论

在Go语言中,使用channel可以进行协程间的通信。当一个协程读取一个没有写入数据的channel时,它会被阻塞,直到有数据可读取。如果在程序中没有其他的协程往这个channel中写入数据,那么这个协程将会一直等待下去。

根据您提供的代码片段,ch := make(chan struct{})定义了一个不带缓冲的channel。这意味着当协程读取这个channel时,如果没有其他协程写入数据,它将会被阻塞。而 <-ch 则是在程序结尾处读取这个channel,这将导致程序阻塞直到有数据可读取。

可能情况是,这段代码是为了确保程序不会在此处退出,并保持运行状态。这可能是因为程序的其他部分依赖于在其他协程中往这个channel中写入数据,以便协程间的同步或其他目的。需要进一步查看程序的上下文和整体结构才能确定实际的目的。

7个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!