美文网首页
【channel】泄露 & 注意事项

【channel】泄露 & 注意事项

作者: 观镜人 | 来源:发表于2017-02-06 17:41 被阅读0次
  • 知识点:
    main主协程退出,其他协程全部退出
    过去我们实现多线程通信通常通过共享内存来实现, 并需要对这块内存区进行枷锁操作, golang中我们可以通过channel实现协程通信
    channel可以接受任何类型数据,并且类型安全
    select多路复用:golang中用select关键字来检索channel的IO事件,并支持多channel同时检索,实现多路复用。select只接受IO操作,不接受表达式。
    读写channel可以隐式转换只读只写,反之不可以。
    注意通道传递方式,引用类型。实验转换之后外部chan是否权限改变。
  • 注意事项:以下
/*
注意事项:
    chan,一定是一个协程写,一个协程读,若在一个协程里又写又读,肯定死锁!因为在一个指令发生之后,会停止并等待
    buffer chan 可以在一个协程里又写又读(有范围)
    不能使用    var ch chan int 的形式声明,因为 nil chan无法receive也无法send
    尽量不要在函数里面声明chan,其他goroutine不好接收。
    chan等待没有回复,发生在其他goroutine会阻塞,不影响主程序。发生在主程,deadlock!
    若为主程序设置开关,一定在其他goroutine不会被阻塞的地方写入。
*/
package main

import (
    . "fmt"
    "strconv"
    "time"
)

func main() {
    go produce(ch5)
    go consume(ch5)
    time.Sleep(1*time.Second)
    m2()


    <- sw   //主程序等待produce结束
}

//product
type product struct {
    name      string
    attribute string
}
var ch1 = make(chan int)
var ch2 = make(chan int)
//var ch3 = make(chan int)
var ch5 = make(chan product)
//var ch5 = make(chan product,9) //此处,若ch5为buffer chan,会有何不同
var sw = make(chan bool)

//关于权限,隐式转换,当外部读写chan作为实参传入m1后,ch权限为receive-only,不可send。
//但是等m1返回之后,外部chan依然是receive-send。转换时,权限只能往小,不能往大。
func produce(ch chan<- product){
    println("produce")

    for i := 0; i < 9; i++ {
        ch <- product{"小浣熊",strconv.Itoa(i)}
        println(i)
    }
    sw <- true // 阻塞作用


}

func consume(ch chan product) {
    Println("consume")
    for {
        Println(<-ch)
    }

}

//多路复用
func m2()  {
    select {
    case i := <-ch1:
        Println("ch1:",i)
    case i := <-ch2:
        Println("ch2:",i)
    default:
        Println("ch1 ch2 均无写入")
    }

}

相关文章

网友评论

      本文标题:【channel】泄露 & 注意事项

      本文链接:https://www.haomeiwen.com/subject/pmsuittx.html