zoukankan      html  css  js  c++  java
  • Go语言编程读书笔记:Go channel(1)

    Channel是Go语言在语言级别提供的goroutine间的通信方式。我们可以用channel在两个或多个goroutine之间传递消息。channel是进程内的通信方式,因此通过channel传递对象的过程和调用函数是的参数传递行为比较一致,比如也可以传递指针等。如果需要跨进程通信,建议用分布式系统的方法来解决,比如用socket或HTTP等通信协议。

    channel是类型相关的,也就是说,一个channel只能传递一种类型的值。这个类型需要在声明channel时指定。

    一般channel的声明形式为:

    var chanName chan ElementType

    举个栗子,我们声明一个传递类型为int的channel:

    var ch chan int

    或者声明一个map,元素是bool的channel:

    var m map[string] chan bool

    定义一个channel,直接使用make()函数即可:

    ch := make(chan int)

    在channel的用法中,最常见的包括写入和读出,将一个数据写入channel的语法很直观:

    ch <- value

    向channel写入数据通常会导致程序阻塞,直到有其他goroutine从这个channel中读取数据,从channel中读取数据的语法是:

    value := <- ch

    示例:

    在这个例子中,我们定义了一个10个channel的数组chs,并把数组中的每个channel分配给10个不同的goroutine,在每个goroutine的print完成后,我们通过ch <- 1向channel中写入一个数据,在这个channel被读取前,这个操作是阻塞的。在所有goroutine启动完成后,我们通过<-ch从10个channel中依次读取数据,在数据写入channel前,这个操作也是阻塞的。这样就实现了锁的功能。

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func Count(ch chan int) {
    	fmt.Println("Counting")
    	time.Sleep(time.Second)
    	ch <- 1
    }
    
    func main(){
    	chs := make([]chan int,10)
    	for i := 0;i<10;i++ {
    		chs[i] = make(chan int)
    		go Count(chs[i])
    	}
    
    	for _,ch := range(chs){
    		<-ch
    	}
    }
    

     坑:

    channel默认上是阻塞的,也就是说,如果Channel满了,就阻塞写,如果Channel空了,就阻塞读。于是,我们就可以使用这种特性来同步我们的发送和接收端。

    channel <-,发送一个新的值到通道中 <-channel,从通道中接收一个值,这个更像有两层含义,一个是会返回一个结果,当做赋值来用:msg := <-channel;另外一个含义是等待这个channel发送消息,所以还有一个等的含义在.所以如果你直接写fmt.Print(<-channel)本意只是想输出下这个chan传来的值,但是其实他还会阻塞住等着channel来发.

    默认发送和接收操作是阻塞的,直到发送方和接收方都准备完毕。

    package main
    
    import "fmt"
    
    func main() {
    	messages := make(chan string)
    	go func() {
    		messages <- "ping"
    	}()
    	msg := <-messages
    	fmt.Println(msg)
    }
    
    //output:ping
    

     如果是下面这样写,就会报错,因为msg还在等待message来传送值

    func main() {
    	messages := make(chan string)
    
    
    	msg := <-messages
    
    	messages <- "ping"
    	fmt.Println(msg)
    }
    
    //fatal error: all goroutines are asleep - deadlock!
    
    //goroutine 1 [chan receive]:
    

      

     

  • 相关阅读:
    ajaxfileupload
    ASP.NET从MVC5升级到MVC6
    jvm(13)-线程安全与锁优化(转)
    成为顶尖自由职业者必备的7个软技能之一:沟通(转)
    在ubuntu安装Phabricator(转)
    查看mysql当前表使用的存储引擎(转)
    在Java中如何使用jdbc连接Sql2008数据库(转)
    漂亮的ActionBar效果
    Android smartimageview网络图片查看器
    Android 图板之保存图像
  • 原文地址:https://www.cnblogs.com/nurruden/p/9842146.html
Copyright © 2011-2022 走看看