channel

总结

数据先进先出

// 声明方式,在此ElemType是指此管道所传递的类型
var chanName chan ElemType
// 声明一个传递类型为int的管道
var ch chan int
// 声明一个map,元素是bool型的channel
var m map[string] chan bool

// 定义语法,定义需要使用内置函数make()即可,下面这行代码是声明+定义一个整型管道
ch := make(chan int)
// 事先定义好管道的size,下面这行代码定义管道的size为100
ch := make(chan int, 100)

// 由管道中读写数据,<-操作符是与最左边的chan优先结合的
// 向管道中写入一个数据,在此需要注意:向管道中写入数据通常会导致程序阻塞,直到有
// 其他goroutine从这个管道中读取数据
ch<- value
// 读取数据,注意:如果管道中没有数据,那么从管道中读取数据会导致程序阻塞,直到有数据
value := <-ch

// 单向管道
var ch1 chan<- float64     // 只能向里面写入float64的数据,不能读取
var ch2 <-chan int         // 只能读取int型数据

// 关闭channel,直接调用close()即可
close(ch)
// 判断ch是否关闭,判断ok的值,如果是false,则说明已经关闭(关闭的话读取是不会阻塞的)
x, ok := <-ch

管道就是各个协程间通讯的一个方法

package main
import "fmt"

func print(ch chan int) {
	fmt.Println("Hello world")
	ch<- 1
}

func main() {
	chs := make([]chan int, 10)
	for i := 0; i < 10; i++ {
		chs[i] = make(chan int)
		go print(chs[i])
	}

	for _, ch := range(chs){
		<-ch
	}
}

如果修改为..还没来得及处理,主线程就结束了

func print(ch chan int){
    ch<- 1
    fmt.Println("Hello world")
}

channel

使用场景:等待mysql/curl返回
写入数据

package main

import (
    "fmt"
)

var _ = fmt.Sprintf("")

var ch chan int = make(chan int, 1)

func main() {
   //写入channel
    ch <- 1
    //读取channel
    mych := <-ch                                                                                                                      
    fmt.Println(mych)

    var stop string
    fmt.Scanln(&stop)
    fmt.Println(stop)
}****

select
支持多个channel等待,设置超时,和default

package main

import (
	"fmt"
	"runtime"
	"time"
)
var ch chan int = make(chan int, 1)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	go writeCh()
	readCh()

	var stop string
	fmt.Scanln(&stop)
	fmt.Println(stop)
}

func readCh() {
	select {
	case ch1 := <-ch:
		fmt.Println(ch1)
		return
		//设置1秒超时
	case <-time.After(time.Second*3):
		fmt.Println("read timeout")
	}
}

func writeCh() {
	//等待2秒后写入,使超时生效
	time.Sleep(time.Second * 2)
	ch <- 1
}

channel的关闭

package main                                                                                                                          

import (
    "fmt"
    "runtime"
    "time"
)

var _ = fmt.Sprintf("")

var ch chan int = make(chan int, 1)

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())

    go writeCh()
    readCh()

    var stop string
    fmt.Scanln(&stop)
    fmt.Println(stop)

    close(ch)
               
    var more bool
    var chi int
    //第一个返回channel的值,第二个返回是否还有更多的数据
    chi, more = <-ch
    fmt.Println(chi, more)
                 
    //关闭后再往channel中写入会报错
    //ch <- 1    
}                
                 
func readCh() {
    select { 
    case ch1 := <-ch:
        fmt.Println(ch1)
    case <-time.After(time.Second):
        fmt.Println("read timeout")
    }
}

func writeCh() {
    //time.Sleep(time.Second * 2)
    ch <- 1
}
posted @ 2017-05-16 21:26  zhangshihai1232  阅读(156)  评论(0)    收藏  举报