다음 Go 코드 예에서는 c <- byte(0)
과 close(c)
사이의 경쟁 조건이 있습니다. 코드가 go test -race
으로 실행되면 신호가 보내집니다.이동 채널을 닫을 때의 이동 조건
func TestRace(t *testing.T) {
var c = make(chan byte, 20)
go func() {
defer func() {
if r := recover(); r == nil {
t.Error("expected panic error")
}
}()
for i := 0; i < 25; i++ {
c <- byte(0)
}
t.Error("expected a panic")
}()
close(c)
}
어떻게하면이 경쟁 조건을 피할 수 있습니까?
편집 :
func TestRace(t *testing.T) {
var c = make(chan byte, 20)
var done = make(chan struct{})
go func() {
for i := 0; i < 25; i++ {
select{
case c <- byte(0):
case <-done:
close(c)
return
}
}()
close(done)
}
이 경쟁 조건이되지 않고 깨끗합니다 그의 의견에 Icza 제안에 따라, 여기에 솔루션입니다. 그것은 어리석은 간단한 예입니다. select가 오버 헤드를 추가한다고 들었지만, 사용 사례와 관련이 없기 때문에이를 조사하지 않았습니다.
goroutine이 경쟁 조건을 제거하기 전에 실행되도록'close (c)'를 위로 이동하십시오. 어떤 이유로 든 채널을 닫고 그 채널에 글쓰기의 책임이 다른 경쟁자에 속해야한다면 경쟁 조건이 항상 존재할 수 있습니다. WaitGroups 및 다른 잠금을 사용하면 안전하게 수행 할 수 있습니다. – whytheplatypus