2.25 Go之Goroutine(轻量级线程)

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()函数并发执行,每隔一秒打印一次计数器,maingoroutine则等待用户输入,两个行为可以同时进行

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

  1. 使用你们函数创建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特点:

所有goroutinemain()函数结束时会一同结束

终止goroutine的最好方法就是自然返回goroutine对应的函数。

截止Go 1.9版本,暂时没有标准接口获取goroutineID

posted @ 2022-02-28 10:21  俊king  阅读(67)  评论(0)    收藏  举报