zoukankan      html  css  js  c++  java
  • 【转】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的运行上,多线程运行加速效果是很明显的.

  • 相关阅读:
    字王20年
    [转]Birdfont 2.10 发布,字体编辑器
    vs2013编译boost库
    c++ 完成端口资料
    获取输入法输入内容及后选项的钩子
    unicode string和ansi string的转换函数及获取程序运行路径的代码
    c++实现输入法窗口自定义的代码
    在固定长方形里产生渐变
    监听某个div或其它标签的大小改变来执行相应的处理
    64位SqlServer通过链接服务器与32位oracle通讯
  • 原文地址:https://www.cnblogs.com/oxspirt/p/15516457.html
Copyright © 2011-2022 走看看