外部リソースに接続するプログラムや、それ以外の方法で実行時間を制御する必要があるプログラムでは、タイムアウトが重要です。Go でタイムアウトを実装するのは、チャネルと select があるため、簡単でエレガントです。
|
|
|

package main
|
|
import (
"fmt"
"time"
)
|
|
func main() {
|
この例では、2 秒後にチャネル c1 に結果を返す外部呼び出しを実行しているとします。チャネルはバッファリングされているため、ゴルーチン内の送信は非ブロッキングであることに注意してください。これは、チャネルが読み取られない場合にゴルーチンのリークを防ぐための一般的なパターンです。
|
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "result 1"
}()
|
タイムアウトを実装する select を次に示します。res := <-c1 は結果を待って、<-time.After は 1 秒のタイムアウト後に値が送信されるのを待ちます。select は最初に準備ができた受信処理を実行するため、操作に許可された 1 秒を超えた場合はタイムアウトケースを使用します。
|
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("timeout 1")
}
|
タイムアウトを 3 秒以上に長くすると、c2 からの受信が成功し、結果が出力されます。
|
c2 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(3 * time.Second):
fmt.Println("timeout 2")
}
}
|