假设我们有NCPU
个CPU核心:const NCPU = 4 //对应一个四核处理器
然后我们想把计算量分成NCPU
个部分,每一个部分都和其他部分并行运行。
这可以通过以下代码所示的方式完成(我们且省略具体参数)
func DoAll(){ sem := make(chan int, NCPU) // Buffering optional but sensible for i := 0; i < NCPU; i++ { go DoPart(sem) } // Drain the channel sem, waiting for NCPU tasks to complete for i := 0; i < NCPU; i++ { <-sem // wait for one task to complete } // All done.}func DoPart(sem chan int) { // do the part of the computation sem <-1 // signal that this piece is done}func main() { runtime.GOMAXPROCS(NCPU) // runtime.GOMAXPROCS = NCPU DoAll() }
DoAll()
函数创建了一个sem
通道,每个并行计算都将在对其发送完成信号;在一个 for 循环中NCPU
个协程被启动了,每个协程会承担1/NCPU
的工作量。每一个DoPart()
协程都会向sem
通道发送完成信号。
DoAll()
会在 for 循环中等待NCPU
个协程完成:sem
通道就像一个信号量,这份代码展示了一个经典的信号量模式。(参见 14.2.7)
在以上运行模型中,您还需将GOMAXPROCS
设置为NCPU
(参见 14.1.3)。