好好爱自己!

【转】golang多核的使用

 

 

原文: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的运行上,多线程运行加速效果是很明显的.

posted @ 2021-11-06 12:26  立志做一个好的程序员  阅读(652)  评论(0编辑  收藏  举报

不断学习创作,与自己快乐相处