버퍼링되지 않은 채널을 사용할 때 Go에서 \'치명적인 오류: 모든 고루틴이 절전 모드 - 교착 상태!\'를 해결하는 방법은 무엇입니까?

Barbara Streisand
풀어 주다: 2024-11-25 15:36:17
원래의
690명이 탐색했습니다.

 How to Resolve

"Go: Fatal Error: All Goroutines Are Asleep - Deadlock"

문제:

한 줄의 단어로 구성된 텍스트 파일이 있고 다음을 수행하려고 합니다. 각 단어를 채널에 저장합니다. 이어서 채널에서 이러한 단어를 검색하여 한 번에 하나씩 인쇄하려고 합니다. 다음 코드 조각은 현재 접근 방식을 나타냅니다.

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string)

    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Fields(line)

        for i := range parts {
            file1chan <- parts[i]
        }
    }
    print(file1chan)
}

func print(in <-chan string) {
    for str := range in {
        fmt.Printf("%s\n", str)
    }
}
로그인 후 복사

그러나 이 코드를 실행하면 "치명적인 오류: 모든 고루틴이 잠자기 상태입니다. 교착 상태입니다!"라는 오류 메시지가 나타납니다.

해결책:

file1chan이 버퍼링되지 않았기 때문에 오류가 발생합니다. 채널. 이 채널로 값을 보내려고 하면 무기한 차단되어 수신자를 기다립니다. 이 교착 상태를 해결하려면 채널에 값을 전송하는 새 고루틴을 시작하거나 채널을 버퍼링된 것으로 선언하면 됩니다. 아래에는 두 가지 접근 방식이 설명되어 있습니다.

새 고루틴 사용:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string)

    // Start a new goroutine to send strings down file1chan
    go func() {
        for scanner.Scan() {
            line := scanner.Text()
            parts := strings.Fields(line)

            for i := range parts {
                file1chan <- parts[i]
            }
        }
        close(file1chan) // Close the channel when done sending.
    }()

    print(file1chan) // Read strings from file1chan
}

func print(in <-chan string) {
    for str := range in {
        fmt.Printf("%s\n", str)
    }
}
로그인 후 복사

버퍼 채널 사용:

단일 문자열을 처리하면 크기가 버퍼링된 채널을 정의할 수 있습니다. 1:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("D:\input1.txt")
    scanner := bufio.NewScanner(f)
    file1chan := make(chan string, 1) // Buffer size of one

    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Fields(line)

        for i := range parts {
            file1chan <- parts[i]
        }
    }

    close(file1chan) // Close the channel when done sending.
    print(file1chan)
}

func print(in <-chan string) {
    for str := range in { // Read all values until channel gets closed
        fmt.Printf("%s\n", str)
    }
}
로그인 후 복사

위 내용은 버퍼링되지 않은 채널을 사용할 때 Go에서 \'치명적인 오류: 모든 고루틴이 절전 모드 - 교착 상태!\'를 해결하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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