php 편집자 Baicao는 이 기사에서 "WaitGroups 및 버퍼 채널을 사용하는 Go 코드에서 교착 상태가 발생하는 이유는 무엇입니까?"라는 일반적인 질문에 답할 것입니다. Go 언어에서 WaitGroups 및 버퍼 채널은 일반적으로 동시 프로그래밍 도구로 사용됩니다. 그러나 때로는 이를 사용하는 코드에서 교착 상태 상황이 발생할 수 있습니다. 이 기사에서는 교착 상태의 원인을 자세히 살펴보고 독자가 이 문제를 방지하는 데 도움이 되는 솔루션을 제공합니다. 당신이 초보자이든 숙련된 Go 개발자이든 이 글은 귀중한 정보를 제공할 것입니다.
대기 그룹, 버퍼 채널 및 교착 상태
이 코드는 교착 상태를 유발하지만 그 이유는 확실하지 않습니다. 나는 몇 가지 다른 장소에서 뮤텍스를 사용해 보았고 별도의 go 루틴 내부와 외부의 채널을 닫았지만 여전히 동일한 결과를 얻었습니다.
한 채널(inputchan)을 통해 데이터를 보내고 다른 채널(outputchan)에서 데이터를 읽으려고 합니다
package main import ( "fmt" "sync" ) func listStuff(wg *sync.WaitGroup, workerID int, inputChan chan int, outputChan chan int) { defer wg.Done() for i := range inputChan { fmt.Println("sending ", i) outputChan <- i } } func List(workers int) ([]int, error) { _output := make([]int, 0) inputChan := make(chan int, 1000) outputChan := make(chan int, 1000) var wg sync.WaitGroup wg.Add(workers) fmt.Printf("+++ Spinning up %v workers\n", workers) for i := 0; i < workers; i++ { go listStuff(&wg, i, inputChan, outputChan) } for i := 0; i < 3000; i++ { inputChan <- i } done := make(chan struct{}) go func() { close(done) close(inputChan) close(outputChan) wg.Wait() }() for o := range outputChan { fmt.Println("reading from channel...") _output = append(_output, o) } <-done fmt.Printf("+++ output len: %v\n", len(_output)) return _output, nil } func main() { List(5) }
주 함수의 코드는 연속적입니다. 먼저inputchan
에 3k 값을 쓰려고 inputchan
然后将从 outputchan
그런 다음
outputchan에서 값을 읽습니다. 코드>. <p>
</p>첫 번째 단계의 코드 블록: <ul>
<li>
<code>inputchan
之前,outputchan
不会流失任何内容,因此工作人员最终会在第一个 1k 值之后卡在 outputchan <- i
3k 값을
inputchan
中消耗资源,main
将在大约 2k 个值之后卡在 inputchan <- i
직원이
inputchan <- i
) 和最终消费者 (for o := range outputchan {
이 문제를 해결하는 한 가지 방법은 생산자(
이 액터 중 하나를 메인 고루틴에 유지하고 다른 액터에 대해 새 액터를 스핀할 수 있습니다. 예:
으아악 https://www.php.cn/link/80e4c54699b5b8cf8c67dd496909fceb
done
的操作顺序很重要;通道 done
和 outputchan
只能在 wg.done()
한 가지 추가 참고 사항: 서라운드 신호 완료되면 모든 직원에게 문을 닫도록 지시합니다
위 내용은 WaitGroups 및 버퍼 채널을 사용하는 Go 코드에서 교착 상태의 원인은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!