golang语言 并发

main goroutine返回时,所有goroutine都会被直接打断,程序退出

go f(x,y),f、x、y的求值发生在当前goroutine中,f的执行发生在新goroutine中

goroutine运行在相同的地址空间中,访问共享内存需要同步

未初始化的channel类型变量的值为nil,在nil信道上进行发送、接收、range,将永远阻塞

make可创建初始化的channel,并接受一个可选的容量参数,

channel会引用make创建的底层数据结构,复制的新channel会引用相同的底层数据结构

channel是先进先出的

无缓存的channel,接收者收到数据发生在唤醒发送者goroutine之前

make(chan int, 100)

chan<- chan int // 等价于 chan<- (chan int)

chan<- <-chan int // 等价于 chan<- (<-chan int)

<-chan <-chan int // 等价于 <-chan (<-chan int)

chan (<-chan int)

close

内建函数 close(c) 标明不再有值会在信道c上发送。

关闭channel可以起到广播的作用

向已关闭的信道上发送会引发panic。

重复关闭channel或者关闭nil值的channel会抛出panic,关闭一个只接收的channel会引发编译错误

关闭channel时,如果该channel的发送goroutine队列不为空,那么这些goroutine将panic

在已关闭的信道上接收,可以接收到之前已成功发送的数据,如果信道里已经没有数据了,那么会立即产生一个零值的数据。可以用x,ok := <-c的形式,判断c是否被关闭

range c 会在c被关闭后结束循环。

当一个channel不被引用时,无论它是否被关闭,都会被垃圾回收。

select

最多有一个default,可以在任何位置,没有初始化语句,不能fallthrough

多个case就绪,随机选择一个。

没有case就绪,且没有default,将永远阻塞

所有channel都是nil值,且没有default,将永远阻塞

没有case,select { } 永远阻塞

select {

case <-ch1:

// ...

case x := <-ch2:

// ...use x...

case ch3 <- y:

// ...

default:

// ...

}

channel的方向

chan T // 可以被用来发送和接收类型T的值 chan<- float64 // 只能被用来发送浮点数 <-chan int // 只能被用来接收整数

双向的channel可以赋值给单向的channel,此时会做一个隐式类型转换。单向不能赋值给双向

chan<- 和 <-chan 也不能相互转换

for {

  select {

  case d := <-ch: // ch阻塞时会不停地循环

  default:

  }

}

for {

  select {

  case d := <-ch: // ch被关闭时会不停地循环

  }

}

x, y := <-c, <-c

猜你喜欢

转载自www.cnblogs.com/ts65214/p/12976451.html