zoukankan      html  css  js  c++  java
  • go语言之进阶篇 channel介绍

    1、channel介绍

    和map类似,channel也一个对应make创建的底层数据结构的引用。

     当我们复制一个channel或用于函数参数传递时,我们只是拷贝了一个channel引用,因此调用者何被调用者将引用同一个channel对象。和其它的引用类型一样,channel的零值也是nil。

     定义一个channel时,也需要定义发送到channel的值的类型。channel可以使用内置的make()函数来创建:

        make(chan Type) //等价于make(chan Type, 0)
        make(chan Type, capacity)

     当 capacity= 0 时,channel 是无缓冲阻塞读写的,当capacity> 0 时,channel 有缓冲、是非阻塞的,直到写满 capacity个元素才阻塞写入。

     channel通过操作符<-来接收和发送数据,发送和接收数据语法:

        channel <- value      //发送value到channel
        <-channel             //接收并将其丢弃
        x := <-channel        //从channel中接收数据,并赋值给x
        x, ok := <-channel    //功能同上,同时检查通道是否已关闭或者是否为空

    默认情况下,channel接收和发送数据都是阻塞的,除非另一端已经准备好,这样就使得goroutine同步变的更加的简单,而不需要显式的lock。

    示例:

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    //全局变量,创建一个channel
    var ch = make(chan int)
    
    //定义一个打印机,参数为字符串,按每个字符打印
    //打印机属于公共资源
    func Printer(str string) {
    	for _, data := range str {
    		fmt.Printf("%c", data)
    		time.Sleep(time.Second)
    	}
    	fmt.Printf("
    ")
    }
    
    //person1执行完后,才能到person2执行
    func person1() {
    	Printer("hello")
    	ch <- 666 //给管道写数据,发送
    }
    
    func person2() {
    	<-ch //从管道取数据,接收,如果通道没有数据他就会阻塞
    	Printer("world")
    }
    
    func main() {
    	//新建2个协程,代表2个人,2个人同时使用打印机
    	go person1()
    	go person2()
    
    	//特地不让主协程结束,死循环
    	for {
    
    	}
    }
    

    执行结果:

    hello
    world
    

      

  • 相关阅读:
    htmlUnil-2.33 jar包
    HtmlUnil 不兼容问题
    Java 网页抓取 工具类
    浏览器不兼容
    Chrome常用调试技巧1
    关于社交网络的思考
    google浏览器历史旧版
    EJB是什么Java使用EJB容器的详细概述
    何必言精通——十年杂感(转载)
    搜索优化—如何在Google搜索引擎上排名靠前Google左侧排名
  • 原文地址:https://www.cnblogs.com/nulige/p/10277990.html
Copyright © 2011-2022 走看看