channel(3) 一 基本定义

1.channel概念:

  类似管道pipe

  先进先出

  线程安全,多个goroutine同时访问,不需要加锁

  channel是有类型的,整数类型的channel只能存放整数类型的数据

2.channel声明 

var 变量名 chan 类型
var test chan int
var test chan string
var test chan map[string]string
var test chan stu
var test chan *stu

3.channel类似于map,slice必须进行初始化

var test chan int

test = make(chan int,100)    //在这里如果容量为0,会是什么结果呢?

4.channel接收数据和读取数据

intchan <-10    //把数据发送到管道中

result := <- intchan //从channel中读取数据,并赋值给result

接上面的疑问,如果容量为0,会是什么情况呢?还有一些问题来一一验证

没有初始化的情况:(报错 nil chan)

1
2
3
4
5
6
7
8
9
import(
    "fmt"
)
func main() {
    var c chan int
    c <- 10
    result:= <- c
    fmt.Println(result)  //goroutine 1 [chan send (nil chan)]:
}

初始化后,容量 为0:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import(
    "fmt"
)
func main() {
    var c chan int
    c = make(chan int,0)
    c <- 10
    result:= <- c
    fmt.Println(result)
    /*
    fatal error: all goroutines are asleep - deadlock!
 
goroutine 1 [chan send]:
main.main()
        c:/goclass/src/day8goroutine/channel/main.go:9 +0x60
exit status 2
    */
}

 还是报错,不太明显,我们换一种方法来测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import(
    "fmt"
    "time"
)
func main() {
    var c chan int
    c = make(chan int,0)
    go func(){    //开启一个goroutine
        fmt.Println("start input to the channel")
        c <- 10
        fmt.Println("end input to the channel")
        }()
    time.Sleep(time.Second*100)
    result:= <- c
    fmt.Println(result)
 
}
//运行结果,会立马输出“start input to the channel” 这一行,然后等待100s后,会输入result结果10。因为容量为0的话,指的是channel没有缓存容量 ,就是不能够缓存任何数据,如果容量改为1的话,会立马输出start和end两句话。

 5.channel 权限控制

var intchan chan <- int  //intchan只可接收int类型数据

var intchan <- chan int  //只可以从intchan中读取数据

var intchan chan int   //即可以接收也可也读取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main
 
import(
    "fmt"
    "sync"
)
var waitgroup sync.WaitGroup  
func SendDate(c chan <- string){   //往chan中写入数据,这个类型是只写的
    c <- "beijing"
    c <- "shanghai"
    c <- "guangzhou"
    c <- "shenzhen"
    close(c)  //写完数据关闭channel
    waitgroup.Done()
}
func GetDate(c <- chan string){   //读取chan中的数据,这个类型是只读的
    for {
        input,ok :=<-c    //检查channel 是否关闭
        if !ok{
            fmt.Println("the chan is closed")
            break
        }
        fmt.Println(input)
    }
    waitgroup.Done()
}
func main() {
    c := make(chan string)
    waitgroup.Add(2)
    go SendDate(c)
    go GetDate(c)
    waitgroup.Wait()  //等待所有的goroutine执行完成
}

  上面的代码中有权限的控制,goroutine和chan相结合。还有一个检查chan是否关闭

    input,ok := <-c

遍历chan中的元素:

for input := range c{
        fmt.Println(input)
    }

 

posted @   whj999  阅读(772)  评论(0编辑  收藏  举报
编辑推荐:
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
点击右上角即可分享
微信分享提示