文章引用自

Golang中runtime的使用

runtime调度器是非常有用的东西,关于runtime包几个方法:

  • Gosched:让当前线程让出cpu以让其他线程运行,它不会挂起当前线程,因此当前线程未来会继续执行

  • NumCPU:返回当前系统的CPU核数量

  • GOMAXPROCS:设置最大的可同时使用的CPU核数

  • Goexit:退出当前goroutine(但是defer语句会照常执行)

  • NumGoroutine:返回真该执行和排队的任务总数

  • GOOS:目标操作系统

  • GOROOT:返回本机的GO路径
package main

import "fmt"
import "runtime" func main() {
fmt.Println("cpus:", runtime.NumCPU()) // 返回当前系统的CPU核数量
fmt.Println("goroot:", runtime.GOROOT()) //
fmt.Println("NumGoroutine:", runtime.NumGoroutine()) // 返回真该执行和排队的任务总数
fmt.Println("archive:", runtime.GOOS) // 目标操作系统
} 运行结果
cpus: 12
goroot: /usr/local/go
NumGoroutine: 1
archive: darwin

  

GOMAXPROCS

  // 修改最大可同时使用CPU核数

Golang默认所有任务都运行在一个cpu核里,如果要在goroutine中使用多核,可以使用runtime.GOMAXPROCS函数修改,当参数小于1时使用默认值。

package main
import "fmt"
import "runtime"
import "time" func init(){
runtime.GOMAXPROCS(4) // 修改最大可同时使用CPU核数
} func main(){
t := time.Now().Nanosecond()
for i:=0;i<100000;i++{
fmt.Println(i*i*i*i)
}
t2 := time.Now().Nanosecond()
fmt.Println(t2-t)
}

  

Gosched

  // 让当前线程让出cpu以让其他线程运行,它不会挂起当前线程,因此当前线程未来会继续执行

这个函数的作用是让当前goroutine让出CPU,当一个goroutine发生阻塞,Go会自动地把与该goroutine出于同一系统线程的其他goroutine转移到另一个系统线程上去,使得这些goroutine不阻塞。

package main

import (
"fmt"
"runtime"
) func init() {
runtime.GOMAXPROCS(1) //使用单核
} func main() {
exit := make(chan int)
go func() {
defer close(exit)
go func() {
fmt.Println("b")
}()
}() for i := 0; i < 4; i++ {
fmt.Println("a:", i) if i == 1 {
runtime.Gosched() //切换任务
}
}
<-exit
}

  

在windows系统上,结果为:

    a: 0
a: 1
a: 2
a: 3

  

切换成多核,每次运行的结果都不一样:

package main

import (
"fmt"
"runtime"
) func main() {
runtime.GOMAXPROCS(4)
exit := make(chan int)
go func() {
defer close(exit)
go func() {
fmt.Println("b")
}()
}() for i := 0; i < 10; i++ {
fmt.Println("a:", i) if i == 4 {
runtime.Gosched() //切换任务
}
}
<-exit
}

  

总结:多核比较适合那种CPU密集型程序,如果是IO密集型使用多核会增加CPU切换的成本。

GOMAXPROCS和sync配合使用

sync.WaitGroup只有三个方法,Add(),Done()和Wait()。其中Done()是Add(-1)的别名。简单来说,使用Add()添加计数,Done()减少一个计数,计数不为0,阻塞Wait()的运行。

package main

import (
"runtime"
"sync"
"fmt"
) func main(){
runtime.GOMAXPROCS(2)
var wg sync.WaitGroup
wg.Add(2)
fmt.Printf("Starting go routines")
go func(){
defer wg.Done()
for char := 'a';char<'a'+26;char++{
fmt.Printf("%c",char)
}
}()
go func() {
defer wg.Done()
for number := 1;number<27;number++{
fmt.Printf("%d",number)
}
}() fmt.Println("\nWaiting to finish")
wg.Wait()
fmt.Println("\n terminating program")
}

  

运行结果:

Starting go routines
Waiting to finish
1234567891011121314151617181920212223242526abcdefghijklmnopqrstuvwxyz
terminating program

  

总结:首先是wg.Add(2)计数为2,阻塞wg.Wait()的运行,然后是wg.Done()减少计数到0,放开wg.Wait()的运行。

runtime.Caller

  Caller 方法反应的是堆栈信息中某堆栈帧所在文件的绝对路径和语句所在文件的行数。而 skip 表示的是从下往上数第几个堆栈帧。如果要打印全部堆栈信息可以直接使用 debug.PrintStack() 来实现。

  

  func Caller(skip int) (pc uintptr, file string, line int, ok bool)

  参数:skip是要提升的堆栈帧数,0-当前函数,1-上一层函数,....

  

  返回值:

   pc是uintptr这个返回的是函数指针

  file是函数所在文件名目录

  line所在行号

   ok 是否可以获取到信息

示例:

我们分别打印skip为0-3的相关信息

package main

import (
"fmt"
"runtime"
) func main() {
for i := 0 ; i< 4; i++ {
test(i)
}
} func test(skip int) {
call(skip)
} func call(skip int) {
pc,file,line,ok := runtime.Caller(skip)
pcName := runtime.FuncForPC(pc).Name() //获取函数名
fmt.Println(fmt.Sprintf("%v %s %d %t %s",pc,file,line,ok,pcName))

返回

17412399   /Users/songzhibin/go/src/Songzhibin/study/3.go   19   true   main.call
17412303 /Users/songzhibin/go/src/Songzhibin/study/3.go 15 true main.test
17412294 /Users/songzhibin/go/src/Songzhibin/study/3.go 10 true main.main
16953069 /usr/local/go/src/runtime/proc.go 203 true runtime.main

  

  

Go语言基础之runtime包的更多相关文章

  1. Go语言基础之time包

    Go语言基础之time包 时间和日期是我们编程中经常会用到的,本文主要介绍了Go语言内置的time包的基本用法. Go语言中导入包 Go语言中使用import关键字导入包,包的名字使用双引号(”)包裹 ...

  2. Go语言基础之Path包与FilePath包

    文章引用自 path包的使用 package main; import ( "fmt" "path" ) //go语言path包的学习 func main() ...

  3. go语言基础之导入包的常用方法

    1.导入包 示例: 法一 package main //导入包,必须使用,否则编译不过 import "fmt" import "os" func main() ...

  4. Go语言基础之包

    Go语言基础之包 在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的.本文介绍了Go语言中如何定义包.如何导出包的内容及如何导入其他包. Go语言的包(packag ...

  5. Go语言基础包之net/http

    Go语言基础包之net/http Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现. net/http介绍 Go语言内置的net/http包提供了HTTP客户端和服务端的 ...

  6. GO学习-(15) Go语言基础之包

    Go语言基础之包 在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的.本文介绍了Go语言中如何定义包.如何导出包的内容及如何导入其他包. Go语言的包(packag ...

  7. [06 Go语言基础-包]

    [06 Go语言基础-包] 包 什么是包,为什么使用包? 到目前为止,我们看到的 Go 程序都只有一个文件,文件里包含一个 main 函数和几个其他的函数.在实际中,这种把所有源代码编写在一个文件的方 ...

  8. go语言之进阶篇runtime包中 Gosched Goexit GOMAXPROCS的使用

    一.runtime包 1.Gosched的使用 runtime.Gosched() 用于让出CPU时间片,让出当前goroutine的执行权限,调度器安排其他等待的任务运行,并在下次某个时候从该位置恢 ...

  9. Golang 入门系列(三)Go语言基础知识汇总

    前面已经了 Go 环境的配置和初学Go时,容易遇到的坑,大家可以请查看前面的文章 https://www.cnblogs.com/zhangweizhong/category/1275863.html ...

随机推荐

  1. 使用Python发送、订阅消息

    使用Python发送.订阅消息 使用插件 paho-mqtt 官方文档:http://shaocheng.li/post/blog/2017-05-23 Paho 是一个开源的 MQTT 客户端项目, ...

  2. [P4550] 收集邮票 - 概率期望,dp

    套路性地倒过来考虑,设\(f[i]\)表示拥有了\(i\)种票子时还需要多少次购买,\(g[i]\)表示还需要多少钱 推\(g[i]\)递推式时注意把代价倒过来(反正总数一定,从顺序第\(1\)张开始 ...

  3. Motif

    Motif discovery is in loose terms the problem of finding interesting patterns in sequences. motif: i ...

  4. C++——类与对象

    1.抽象: 是对具体对象(问题)进行概括,抽出这一类对象的公共性质并加以描述的过程. 1.1 先注意问题的本质描述,其次是实现过程和细节: 1.2 数据抽象:描述某类对象的属性或状态(对象相互区别的物 ...

  5. SpringBoot开发快速入门

    SpringBoot开发快速入门 目录 一.Spring Boot 入门 1.Spring Boot 简介 2.微服务 3.环境准备 1.maven设置: 2.IDEA设置 4.Spring Boot ...

  6. H5Plus 入门学习-Dcloud H5+ API调用实例

    使用API Reference完整简单的操作,更多操作查看官方文档. 最后提供项目的下载地址[下载][一款移动APP演示]

  7. 【STM32H7教程】第59章 STM32H7的DAC基础知识和HAL库API

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第59章       STM32H7的DAC基础知识和HAL库 ...

  8. CentOS7安装配置Apache、PHP和MySQL

    一.安装Apache sudo yum install httpd 安装成功后,Apache操作命令: systemctl start httpd //启动apache systemctl stop ...

  9. WEB-INF目录与META-INF目录的作用(转载)

    /WEB-INF/web.xml Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则. /WEB-INF/classes/包含了站点所有用的 class 文件,包括 ser ...

  10. Educational Codeforces Round 76 (Rated for Div. 2) C. Dominated Subarray

    Let's call an array tt dominated by value vv in the next situation. At first, array tt should have a ...