WaitGroups 및 버퍼 채널을 사용하는 Go 코드에서 교착 상태의 원인은 무엇입니까?

PHPz
풀어 주다: 2024-02-09 11:09:30
앞으로
752명이 탐색했습니다.

使用 WaitGroups 和 Buffered Channels 的 Go 代码中出现死锁的原因是什么?

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 的操作顺序很重要;通道 doneoutputchan 只能在 wg.done()한 가지 추가 참고 사항: 서라운드 신호 완료되면 모든 직원에게 문을 닫도록 지시합니다

    🎜 으아악

    위 내용은 WaitGroups 및 버퍼 채널을 사용하는 Go 코드에서 교착 상태의 원인은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:stackoverflow.com
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    최신 이슈
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿