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
<-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循環就會退出,就不會有更多的郵件被髮送。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章