Home  >  Article  >  Backend Development  >  Buffered channel scope in Go is blocking

Buffered channel scope in Go is blocking

WBOY
WBOYforward
2024-02-09 09:42:30690browse

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")

Output

1
2

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,
    })

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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete