golang使用channel传递信号

原文链接:https://medium.com/@matryer/golang-advent-calendar-day-two-starting-and-stopping-things-with-a-signal-channel-f5048161018

使用channel在goroutines中传递信号

在go里,使用channelgoroutines间交流数据是一个很好的方式,但是也可以使用它去传递信号。

传递信号时,使用空的struct作为channel的类型,只表示信息传递。另一方面,它不会占用内存空间,一个空的struct没有任何的属性。你可以到这里查看

下面一个信号channel

var signal chan struct{}

可以使用go的内置make函数初始化它:

signal := make(chan struct{})

下面的代码会被阻塞,直到某些值被发送到channel中:

<-signal

在这个例子中,我们不在意它的值,这也是为什么我们不传递任何值给它。

类似的,在一个select语句,当收到goroutine外的信号时,可以使用一个关闭的channel去运行不同的代码。

等待某些操作的结束

通过一个阻塞的信号channel,可以等待另一个goroutine中的任务结束:

done := make(chan struct{})
go func() {
  doLongRunningThing()
  close(done)
}()
// do some other bits
// wait for that long running thing to finish
// 阻塞,直到goroutine中关闭channel
<-done
// do more things

同一时间执行多个任务

假设有很多的goroutine在排队,可以通过关闭一个信号channel去触发它们在同一个时间开始执行:

start := make(chan struct{})
for i := 0; i < 10000; i++ {
  go func() {
    <-start // wait for the start channel to be closed
    doWork(i) // do something
 }()
}
// at this point, all goroutines are ready to go - we just need to 
// tell them to start by closing the start channel
close(start)

暂停任务

类似的,也可以使用它去暂停goroutines。当下面的goroutine从一个email channel中收到了数据会进行发送邮件的操作:

loop:
for {
  select {
  case m := <-email:
    sendEmail(m)
  case <-stop: // triggered when the stop channel is closed
    break loop // exit
  }
}

如果stop channel被关闭了,for循环就会退出,就不会有更多的邮件被发送。

  • 更多的channel可以做的事件,到这里查看:VIDEO: GopherCon 2014 A Channel Compendium by John Graham-Cumming.

你可能感兴趣的:(【golang】)