golang 通道有缓冲区

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 通道有缓冲区相关的知识,希望对你有一定的参考价值。

package main

import (
	"fmt"
	"sync"
	"sync/atomic"
	"time"
)

var count int64 = 1

func main() {
	start := time.Now()
	wg := sync.WaitGroup{}
	n := 30  // 并发数量控制
	m := 100 // 任务总量
	wg.Add(m)
	ch1 := make(chan int64, n)
	go func() {
		for i := 0; i < m; i++ {
			ch1 <- count
			atomic.AddInt64(&count, 1)
		}
		close(ch1)
	}()

	for i := 0; i < n; i++ {
		go func(i int) {
			bar(ch1, i+1, &wg)
		}(i)
	}
	wg.Wait()
	fmt.Printf("time:%v", time.Since(start))
}
func bar(ch1 chan int64, id int, wg *sync.WaitGroup) {
	for v := range ch1 {
		func() {
			defer wg.Done()
			foo(v, id)
		}()
	}
}
func foo(s int64, id int) {
	time.Sleep(1 * time.Second) // do something
	fmt.Println(id, s)
}

Golang 中的通道队列有多大?

【中文标题】Golang 中的通道队列有多大?【英文标题】:How big is the channel queue in Golang? 【发布时间】:2017-05-16 20:01:30 【问题描述】:

在 Golang 中,无缓冲通道只是一个 FIFO 队列。任何时候该队列中可以有多少项目?有限制吗?

【问题讨论】:

无缓冲意味着没有缓冲(零)。见Golang - What is channel buffer size?。 我明白了,但是未缓冲与缓冲属性仅影响执行的阻塞,而不是添加到队列中的事物的数量。如果我继续同时调用一个发送到无缓冲通道的 go 例程,我仍然会看到按顺序处理的所有消息,没有任何消息丢失 - 据我所见 你的问题是有多少阻塞的 goroutine 可以等待写入无缓冲通道? @e0k 绝对是的!以及将在哪些订单程序中处理? 只是一个小提示,不要认为缓冲通道是队列 【参考方案1】:

可以在通道本身中的项目数为零,因为它是无缓冲的。但是对于可以在通道上等待发送的 goroutine 的数量没有限制。 (当一个 goroutine 尝试在没有缓冲区或缓冲区已满的通道上发送时,它会阻塞,直到另一个 goroutine 准备好从该通道接收。)

【讨论】:

会接受最有意义的答案,但是 goroutine 的数量真的是无限的吗? 同样在这种情况下,如果通道没有缓冲,goroutines 是否也会以 FIFO 顺序提供服务?还是随机的? 见Max number of goroutines。 goroutines 的数量没有语言上的限制,但是由于每个都使用少量的内存,这施加了物理限制。 当接收器可用时,阻塞的 goroutine 会按照 FIFO 顺序解除阻塞。

以上是关于golang 通道有缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

golang fifo 缓冲通道

Golang 缓冲通道在发送之前接收数据

Golang通道的无阻塞读写的方法示例

在 golang 中创建一片缓冲通道

Golang入门到项目实战 golang并发变成之通道channel

Golang:为啥增加缓冲通道的大小会消除我的 goroutine 的输出?