2.25 Go之Goroutine(轻量级线程)
网络编程
编写Socket网络程序需要提前准备一个线程池,为每个Socket的收发包分配一个线程。
线程池与CPU数量的对应关系:
开发人员需要在线程数量和CPU数量间建立一个对应关系,以保证每个任务能及时地被分配到CPU上进行处理,同时避免多个任务频繁地在线程间切换执行而损失效率。
goroutine机制:
使用者分配足够多的任务,系统能自动帮助使用者把任务分配到CPU上,让这些任务尽量并发运作。
使用普通函数创建goroutine
goroutine特点:
- 
go关键字为一个函数创建一个goroutine
- 
一个函数可以被创建多个 goroutine
- 
一个 goroutine必定对应一个函数
一个普通的goroutine
格式:
普通的goroutine写法:
go 函数名(参数列表)
/*
函数名:要调用的函数名。
参数列表:调用函数需要传入的参数。
*/
注意:
使用go关键字创建goroutine时,被调用的函数返回值会被忽略
需要在goroutine中返回数据,使用后面介绍的通道(channel)特性,通过通道把数据从goroutine中作为返回值传出。
示例代码:
使用go关键字,将running()函数并发执行,每隔一秒打印一次计数器,main的goroutine则等待用户输入,两个行为可以同时进行
package main
import (
    "fmt"
    "time"
)
/*
定义runnning函数,同时定义接收命令行输入函数
并发执行
 */
func runnnig() {
    var times int
    // 无限循环添加
    for {
       times++
       // 打印结果
       fmt.Println("answer:", times)
       // 延时一秒
       time.Sleep(time.Second)
    }
}
// 并发执行
func main() {
    // 定义并发执行程序
    go runnnig()
    // 命令行接收输入
    var input string
    fmt.Scanln(&input)
}
代码执行顺序:

分析:
Go程序在启动时,运行时(runtime)会默认为main()函数创建一个goroutine。在main()函数的goroutine中执行到go running 语句时,归属于running()函数的goroutine被创建,running()函数开始在自己的goroutine中执行。此时,main()继续执行,两个goroutine通过Go程序的调度机制同时运作。
使用匿名函数创建goroutine
go关键字可以为匿名函数或者闭包启动goroutine
- 
使用你们函数创建 goroutine的格式
匿名函数或闭包创建goroutine时,除了将函数定义部分写在go的后面之外,还需要加上匿名函数的调用参数:
go func(参数列表) {
    函数体
}(调用参数列表)
/*
参数列表:函数体内的参数变量列表。
函数体:匿名函数的代码。
调用参数列表:启动 goroutine 时,需要向匿名函数传递的调用参数。--->写在调用参数列表中的才是真实的入参
*/
匿名函数创建goroutine示例:
在main()函数中创建一个匿名函数并为匿名函数启动goroutine。匿名函数没有参数。代码将并行执行定时打印计数的效果
package main
import (
    "fmt"
    "time"
)
/*
使用匿名参数的方法创建一个goroutine
 */
func main() {
    // 声明一个匿名goroutine
    /*
    没有调用参数,所以再启动main的时候会直接被执行
     */
    go func() {
        var times int
        // 无线添加
        for {
           times++
           fmt.Println("tick", times)
           // 等待
           time.Sleep(time.Second)
        }
    }()
    // 接收命令行参数
    var input string
    fmt.Scanln(&input)
}
goroutine特点:
所有goroutine在main()函数结束时会一同结束
终止goroutine的最好方法就是自然返回goroutine对应的函数。
截止Go 1.9版本,暂时没有标准接口获取goroutine的
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号