Go 如何正确使用通道来控制并发性?
我对Go中的并发性还不熟悉,我正在尝试找出如何使用通道来控制并发性。我想做的是有一个循环,在这个循环中,我可以使用一个新的go例程调用一个函数,并在该函数处理时继续循环,我想将运行的例程数量限制为3个。我第一次尝试这样做的代码如下:Go 如何正确使用通道来控制并发性?,go,concurrency,Go,Concurrency,我对Go中的并发性还不熟悉,我正在尝试找出如何使用通道来控制并发性。我想做的是有一个循环,在这个循环中,我可以使用一个新的go例程调用一个函数,并在该函数处理时继续循环,我想将运行的例程数量限制为3个。我第一次尝试这样做的代码如下: func write(val int, ch chan bool) { fmt.Println("Processing:", val) time.Sleep(2 * time.Second) ch <- val % 3 == 0 }
func write(val int, ch chan bool) {
fmt.Println("Processing:", val)
time.Sleep(2 * time.Second)
ch <- val % 3 == 0
}
func main() {
ch := make(chan bool, 3) // limit to 3 routines?
for i := 0; i< 10; i++ {
go write(i, ch)
resp := <- ch
fmt.Println("Divisible by 3:", resp)
}
time.Sleep(20 * time.Second)
}
func写入(val int,ch chan bool){
fmt.Println(“处理:,val)
时间。睡眠(2*时间。秒)
ch这里的问题很简单:
for i := 0; i< 10; i++ {
go write(i, ch)
resp := <- ch
fmt.Println("Divisible by 3:", resp)
}
i:=0;i<10;i++{
去写(i,ch)
resp:=还有一种方法可以并行运行go例程,并等待所有例程返回通道上的值,即使用等待组
。这也有助于同步go例程。如果您使用go例程等待所有例程完成,然后再执行另一个函数,更好的方法是使用等待组
package main
import (
"fmt"
"time"
"sync"
)
func write(val int, wg *sync.WaitGroup, ch chan bool) {
defer wg.Done()
fmt.Println("Processing:", val)
time.Sleep(2 * time.Second)
ch <- val % 3 == 0
}
func main() {
wg := &sync.WaitGroup{}
ch := make(chan bool, 3)
for i := 0; i< 10; i++ {
wg.Add(1)
go write(i, wg, ch)
}
for i := 0; i< 10; i++ {
fmt.Println("Divisible by 3: ", <-ch)
}
close(ch)
wg.Wait()
time.Sleep(20 * time.Second)
}
主程序包
进口(
“fmt”
“时间”
“同步”
)
func write(val int,wg*sync.WaitGroup,ch chan bool){
推迟工作组完成()
fmt.Println(“处理:,val)
时间。睡眠(2*时间。秒)
作为旁注,你真的需要在这里控制并发吗?Goroutines更像是线程池中的任务,而不是操作系统线程。当然,细节有点复杂,但是你可以在内核中发送几十个,而不需要几十个线程上下文切换的开销。仍然有很好的理由控制并发nWalk(例如,下载器可能不希望有1000个并发的输出连接…),但是如果你来自C++或C语言,它们并不像你想象的那么普通。
package main
import (
"fmt"
"time"
"sync"
)
func write(val int, wg *sync.WaitGroup, ch chan bool) {
defer wg.Done()
fmt.Println("Processing:", val)
time.Sleep(2 * time.Second)
ch <- val % 3 == 0
}
func main() {
wg := &sync.WaitGroup{}
ch := make(chan bool, 3)
for i := 0; i< 10; i++ {
wg.Add(1)
go write(i, wg, ch)
}
for i := 0; i< 10; i++ {
fmt.Println("Divisible by 3: ", <-ch)
}
close(ch)
wg.Wait()
time.Sleep(20 * time.Second)
}