原文:http://www.xtgxiso.com/golang%E5%A4%9A%E6%A0%B8%E7%9A%84%E4%BD%BF%E7%94%A8/
上面是設置, runtime.GOMAXPROCS(4), 下面是 runtime.GOMAXPROCS(1), 執行時間差了4倍。
------------------
對於多核編程,go是天生支持,那么我們在什么情況下應該用多核心來加速程序,而在什么情況下用單核即可呢?
現在我們用一簡單的程序來說明下:
package main import ( "runtime" "fmt" "sync" "database/sql" _ "github.com/go-sql-driver/mysql" "time" ) //定義任務隊列 var waitgroup sync.WaitGroup func xtgxiso(num int) { //fmt.Println(num) db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8") if err != nil { fmt.Println(err) } defer db.Close() rows, err := db.Query("select sleep(1) as a") if err != nil { fmt.Println(err) } defer rows.Close() var a string for rows.Next() { err = rows.Scan(&a) if err != nil { fmt.Println(err) } else { //fmt.Println(a) } } waitgroup.Done() //任務完成,將任務隊列中的任務數量-1,其實.Done就是.Add(-1) } func main() { //記錄開始時間 start := time.Now() //設置最大的可同時使用線程數 runtime.GOMAXPROCS(1) for i := 1; i <= 10; i++ { waitgroup.Add(1) //每創建一個goroutine,就把任務隊列中任務的數量+1 go xtgxiso(i) } waitgroup.Wait() //Wait()這里會發生阻塞,直到隊列中所有的任務結束就會解除阻塞 //記錄結束時間 end := time.Now() //輸出執行時間,單位為秒。 fmt.Println(end.Sub(start).Seconds()) }
這個程序是執行十次”select sleep(1) as a“.如果是順序阻塞執行的話,執行時間肯定是10s以上,而我們用的協程不會有這種情況。
我們可以修改“runtime.GOMAXPROCS(1)”來設置最大可同時執行的線程數,對比結果發現,都是1s多點,有時多線程反而會比單線程慢些,這是為什么呢?
這是因為這個程序是IO為主的,啟用多線程反而有上下文切換,所以對於以涉及IO操作的主的程序啟用多線程對於加速程序意義不大,
runtime.GOMAXPROCS(1) 保證了mysql的操作(golang底層走的是非阻塞io)都在一個線程上執行,也就沒有了cpu在多個線程之間來回調度。
那么什么程序啟用多線程呢?我們來看如下程序:
package main import ( "runtime" "fmt" "sync" "time" ) //定義任務隊列 var waitgroup sync.WaitGroup func xtgxiso(num int) { for i:=1;i<=1000000000;i++{ num = num+i num = num-i num = num*i num = num/i } waitgroup.Done() //任務完成,將任務隊列中的任務數量-1,其實.Done就是.Add(-1) } func main() { //記錄開始時間 start := time.Now() //設置最大的可同時使用的線程數 runtime.GOMAXPROCS(1) for i := 1; i <= 10; i++ { waitgroup.Add(1) //每創建一個goroutine,就把任務隊列中任務的數量+1 go xtgxiso(i) } waitgroup.Wait() //Wait()這里會發生阻塞,直到隊列中所有的任務結束就會解除阻塞 線//記錄結束時間 end := time.Now() //輸出執行時間,單位為秒。 fmt.Println(end.Sub(start).Seconds()) }
對比結果發現,多線程比單線程快,所以對於CPU的運行上,多線程運行加速效果是很明顯的.