• 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)

    import(
    	"fmt"
    )
    func main() {
    	var c chan int
    	c <- 10
    	result:= <- c
    	fmt.Println(result)  //goroutine 1 [chan send (nil chan)]:
    }

    初始化后,容量 为0:

    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
    	*/
    }
    

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

    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   //即可以接收也可也读取数据

    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)
        }

     

  • 相关阅读:
    消费券
    .net Core 用户登入身份验证简单的demo
    微信阅读. 电脑版. 标记上一页阅读到的位置. 油猴(Tampermonkey)插件
    Docker.控制台程序.发布
    Docker.容器管理
    Docker.镜像管理
    RestSharp 加号变空格 + HTTP 请求
    在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误
    数据库.Sqlserver.重建索引
    数据库.索引Vs树
  • 原文地址:https://www.cnblogs.com/wanghaijun999/p/8358920.html
Copyright © 2020-2023  润新知