果然,我的 Golang 只使用一个 CPU 是错误的
尝试了一下使用多线程的Go语言编程,因为它可以轻松地利用多个CPU,但结果只有一个CPU达到了100%。
只使用一个CPU
package main
import (
"fmt"
"sync"
"time"
)
func main() {
fmt.Println("start")
var wg sync.WaitGroup
for _, a := range []string{"1", "2"} {
wg.Add(1)
go func(str string) {
i := 0
fmt.Println("I'm " + str)
time.Sleep(1) // 時分割なので2番目が開始するまで待つ
for {
i++;
}
wg.Done()
}(a)
}
wg.Wait()
fmt.Println("end")
}
$ go run calc.go &
start
I'm 1
I'm 2
$ mpstat -P ALL 2
平均値: CPU %usr %idle
平均値: 0 100.00 0.00
平均値: 1 0.25 99.50
是什么导致了这个结果?
将GOMAXPROCS的初始值设为1,这意味着默认情况下会将一个核心分时执行(并行处理),如果要使用多个CPU进行并行处理,则需要将CPU的数量设为GOMAXPROCS的值。
package main
import (
"fmt"
"sync"
"time"
"runtime"
)
func main() {
fmt.Println("start")
fmt.Printf("NumCPU=%d\n", runtime.NumCPU())
runtime.GOMAXPROCS(runtime.NumCPU())
var wg sync.WaitGroup
for _, a := range []string{"1", "2"} {
wg.Add(1)
go func(str string) {
i := 0
fmt.Println("I'm " + str)
time.Sleep(1)
for {
i++;
}
wg.Done()
}(a)
}
wg.Wait()
fmt.Println("end")
}
$ go run calc2.go
NumCPU=2
I'm 1
I'm 2
$ mpstat -P ALL 2
平均値: CPU %usr %idle
平均値: 0 100.00 0.00
平均値: 1 100.00 0.00
并行处理和并行处理
calc.go和calc2.go的处理方式分别是并发处理和并行处理。
在《龙珠》中进行类比说明,
并行处理就像是孙悟空的多重残像拳,悟空以超高速切换不同位置,看起来像是多个人,但实际上只有一个人。
而并列处理就像是天津饭的四身之拳,天津饭真的变成了四个人。
由于并行处理将一个CPU按时间分割运行,所以第二个CPU没有被使用,一直处于闲置状态。
请参阅
来看看 – Go语言的并发与并行性模式 – Qiita
http://qiita.com/hayajo/items/4cd75f87e35e60ae11a9#并行性模式
根据CPU数量限制并行处理数量 | SOTA
http://deeeet.com/writing/2014/07/30/golang-parallel-by-cpu/
为什么没有多核支持?
为什么不支持多核处理器?
前往- sync.WaitGroup的正确使用方法- Qiita
http://qiita.com/ruiu/items/dba58f7b03a9a2ffad65
作为一个只做过动态语言的人,我在38天里学会了如何使用Go语言编写代码 – Qiita
http://qiita.com/suin/items/22662f43b6a6e8728798
在golang中进行并行处理 – golang并行处理-堆栈溢出
在 Github 上的 astaxie/build-web-application-with-golang 倉庫的 master 分支中的 02.7.md 文件。
阅读关于并行和并列的《并行计算技术》一文 – M-Tea
http://www.m-tea.info/2011/03/concurrent-parallel-01.html