Buffered channel scope in Go is blocking

WBOY
Release: 2024-02-09 09:42:30
forward
694 people have browsed it

Go 中缓冲通道的范围是阻塞的

php Xiaobian Yuzai In the Go language, the buffer channel is a powerful and flexible tool. Buffered channels provide a mechanism to synchronize between sending and receiving data, controlling the speed and order of communication. Its scope is blocking, which means that when the channel is full or empty, send and receive operations will be blocked until enough space or data is available. This mechanism can effectively avoid resource competition and deadlock problems in concurrent programs, and improve the reliability and performance of the program. By rationally using buffer channels, developers can better control the execution process of concurrent programs and improve program efficiency and stability.

Question content

There must be something wrong with my brain, but I was blocked while iterating the buffer channel

    results := []search.book{}
    resultsstream := make(chan []search.book, 2)
    defer close(resultsstream)

    // parallelize searches to optimize response time
    for _, src := range sources {
        go src.search(bookname, resultsstream)
    }

    counter := 0
    for sourceresults := range resultsstream {
        counter = counter + 1
        results = append(results, sourceresults...)

        fmt.println(counter)
    }

    fmt.println("never called")
Copy after login

Output

1
2
Copy after login

This proves that 2 sources fill the channel (which is the maximum capacity). What am I missing here? never called is, well, never called.

edit

    var wg sync.WaitGroup
    results := []search.Book{}
    resultsStream := make(chan []search.Book, len(sources))
    defer close(resultsStream)

    // parallelize searches to optimize response time
    for _, src := range sources {
        wg.Add(1)
        go src.Search(bookName, resultsStream, &wg)
    }

    wg.Wait()
    close(resultsStream)
    for sourceResults := range resultsStream {
        results = append(results, sourceResults...)
    }

    c.JSON(http.StatusOK, gin.H{
        "results": results,
    })
Copy after login

Solution

Loop for sourceResults := range resultsStream Repeatedly receive values ​​from the channel until closed. The loop ends once the sender has finished and closed the channel.

You can create a new channel for each parallel search, and once all worker coroutines are completed, you can close the channel. This will end the receiver loop (note: do not close the channel from the receiver side as the sender will not know and sending to a closed channel will cause a panic).

The above is the detailed content of Buffered channel scope in Go is blocking. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template