假设我们的 CPU 核数是 NCPU 个: const NCPU = 4 // 例如:4 代表 4 核处理器,我们将计算划分为 NCPU 部分,每部分与其他部分并行运行。
下面是一个简单的示例(我们忽略具体的参数):
func DoAll() {sem := make(chan int, NCPU)for i := 0; i < NCPU; i++ {// Buffering optional but sensible. 合理的缓冲区选项(个人理解就是和 CPU 的核心数相同)go DoPart(sem)}// 等待 NCPU 任务完成,释放通道 sem 的缓冲区for i := 0; i < NCPU; i++ {<-sem // 等待一个任务完成}// 全部完成。}func DoPart(sem chan int) {// 进行计算的部分...sem <- 1 // 发送一个这部分已经完成的信号,用来释放 sem 的缓冲区}func main() {runtime.GOMAXPROCS = NCPUDoAll()}
- 函数
DoAll()生成一个通道 sem ,在此基础上完成每一个并行计算;在 for 循环中启动NCPU个协程,每一个协程执行全部工作的1/NCPU。通过 sem 发送每一个协程中DoPart()完成的信号。 DoAll()中用一个 for 循环来等待所有 (NCPU个)协程完成计算: 通道 sem 的行为就像一个 semaphore(信号量) ;这个代码展示了一个典型的 信号量模式(可以参见 14.2.7 章节)
在当前的运行模式下,你还必须设置 GOMAXPROCS 为 NCPU(可以参见 14.1.3)
