Go语言学习之runtime包(The way to go)

生命不止,继续 go go go !!!

今天跟大家分享一下runtime package,主要是介绍几个经常用到的方法。

runtime

Package runtime contains operations that interact with Go’s runtime system, such as functions to control goroutines. It also includes the low-level type information used by the reflect package; see reflect’s documentation for the programmable interface to the run-time type system.

上面是官方文档的介绍,我们看到几个关键字:
runtime system
control goroutines
low-level information

其中,goroutines我们还没有详细的介绍,这里暂时不表。

介绍几个跟平台有关的方法:
NumCPU
查看有多少个逻辑cpu, logical cpus

func NumCPU() int

GOROOT
GOROOT returns the root of the Go tree

func GOROOT() string

GOOS
查看目标操作系统
很多时候,我们会根据平台的不同实现不同的操作,就而已用GOOS了:

if runtime.GOOS == "windows" {
    fmt.Println("Hello Windows")
}

下面的例子是上面提到的三个方法的简单应用:

package main

import (
    "fmt"
    "runtime"
)

func main() {
    fmt.Println("cpus:", runtime.NumCPU())
    fmt.Println("goroot:", runtime.GOROOT())
    fmt.Println("os/platform:", runtime.GOOS)
}

运行结果:
Windows平台上:
cpus: 4
goroot: c:\go
os/platform: windows

Linux平台上:
cpus: 1
goroot: /usr/local/go
os/platform: linux

GOMAXPROCS
这个需要着重介绍一下了。

func GOMAXPROCS(n int) int

GOMAXPROCS sets the maximum number of CPUs that can be executing simultaneously and returns the previous setting. If n < 1, it does not change the current setting. The number of logical CPUs on the local machine can be queried with NumCPU. This call will go away when the scheduler improves.

如果要在 goroutine 中使用多核,可以使用 runtime.GOMAXPROCS 函数修改,当参数小于 1 时使用默认值。

Gosched

func Gosched()

Gosched yields the processor, allowing other goroutines to run. It does not suspend the current goroutine, so execution resumes automatically.
这个函数的作用是让当前 goroutine 让出 CPU,当一个 goroutine 发生阻塞,Go 会自动地把与该 goroutine 处于同一系统线程的其他 goroutine 转移到另一个系统线程上去,以使这些 goroutine 不阻塞

下面通过两段代码进行比较:
单核运行:

package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(1)
    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

}

输出:
a: 0
a: 1
a: 2
a: 3
a: 4
b
a: 5
a: 6
a: 7
a: 8
a: 9

多核:

package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(2)
    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

}

每次的运行结果都不一样:
b
a: 0
a: 1
a: 2
a: 3
a: 4
a: 5
a: 6
a: 7
a: 8
a: 9

GOMAXPROCS和sync配合使用
sync这个包我们还没有介绍,这里就说明一点:
sync.WaitGroup只有3个方法,Add(),Done(),Wait()。其中Done()是Add(-1)的别名。简单的来说,使用Add()添加计数,Done()减掉一个计数,计数不为0, 阻塞Wait()的运行

package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    //runtime.GOMAXPROCS(1)
    runtime.GOMAXPROCS(2)

    var wg sync.WaitGroup
    wg.Add(2)

    fmt.Println("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("Waiting To Finish")
    wg.Wait()

    fmt.Println("\nTerminating Program")
}

Go语言学习之runtime包(The way to go)_第1张图片

你可能感兴趣的:(go,Go从入门到不放弃)