golangでのchannelのエラー使用を一度メモします
1962 ワード
この間、プロジェクトの中で問題があって、テストの時までgoroutineがまだ走っていることに気づいて、何だか間違っていて、demoを書いて走って発見して、やはりgoroutineが止まっていないことがあって、くだらないことは多く言わないで、直接コードに行きます
結局、そうです...
tick stopは印刷されていませんか?このtick協程は止まらずtime.Tickというchannelはずっと実行されています.
次にclose(a.stop)の後にコードtimeを挿入した.Sleep(1 time.Millisecond)*奇跡が起こった
このようにすると、close(a.stop)によってchannel信号がキャプチャされ、この方法が繰り返し呼び出されるとエラーが発生するという問題がある.
ここでは外部で手動close channelを利用するのではなく,channelに匿名構造体を伝達しstopに信号を受信させtickコヒーレンスを停止させる
package main
import (
"fmt"
"time"
)
type Adapter struct {
stop chan struct{}
}
func main() {
ch := make(chan struct{})
a := Adapter{stop: make(chan struct{})}
go a.tick()
time.Sleep(3 * time.Second)
close(a.stop)
a.stop = nil
結局、そうです...
index: 0
index: 1
index: 2
index: 3
index: 4
index: 5
index: 6
index: 7
index: 8
index: 9
index: 10
index: 11
index: 12
index: 13
index: 14
index: 15
index: 16
index: 17
index: 18
index: 19
index: 20
...
tick stopは印刷されていませんか?このtick協程は止まらずtime.Tickというchannelはずっと実行されています.
次にclose(a.stop)の後にコードtimeを挿入した.Sleep(1 time.Millisecond)*奇跡が起こった
package main
import (
"fmt"
"time"
)
type Adapter struct {
stop chan struct{}
}
func main() {
ch := make(chan struct{})
a := Adapter{stop: make(chan struct{})}
go a.tick()
time.Sleep(3 * time.Second)
close(a.stop)
time.Sleep(1 * time.Millisecond)
a.stop = nil
index: 0
index: 1
index: 2
tick stop
このようにすると、close(a.stop)によってchannel信号がキャプチャされ、この方法が繰り返し呼び出されるとエラーが発生するという問題がある.
panic: close of closed channel
goroutine 1 [running]:
改善
package main
import (
"fmt"
"log"
"time"
)
type Adapter struct {
stop chan struct{}
}
func main() {
ch := make(chan struct{})
a := Adapter{stop: make(chan struct{})}
go a.tick()
time.Sleep(3 * time.Second)
err := a.closeTick()
if err!=nil{
log.Fatal(err)
}
//test do again
err = a.closeTick()
if err!=nil{
log.Fatal(err)
}
ここでは外部で手動close channelを利用するのではなく,channelに匿名構造体を伝達しstopに信号を受信させtickコヒーレンスを停止させる