Go学习(十六):并发编程-协程使用

1.什么是协程?

协程又称为微线程,是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程,一个线程也可以拥有多个协程。

协程是编译器级的,进程和线程是操作系统级的。协程不被操作系统内核管理,而完全由程序控制,因此没有线程切换的开销。

2.Goroutine

Go语言中的协程叫作GoroutineGoroutineGo程序运行时(runtime)调度和管理,Go程序会智能地将Goroutine中的任务合理地分配给每个CPU。创建Goroutine的成本很小,每个Goroutine的堆栈只有几kb,且堆栈可以根据应用程序的需要增长和收缩。

2.1 Coroutine与Goroutine的区别
  • Goroutine能并行执行, Coroutine只能顺序执行;
  • Goroutine可在多线程环境产生, Coroutine只能发生在单线程。
  • Coroutine程序需要主动交出控制权,系统才能获得控制权并将控制权交给其他 Coroutine
  • Coroutine的运行机制属于协作式任务处理,应用程序在不使用 CPU时,需要主动交出 CPU使用权。如果开发者无意间让应用程序长时间占用 CPU,操作系统也无能为力,计算机很容易失去响应或者死机。
  • Goroutine属于抢占式任务处理,和现有的多线程和多进程任务处理非常类似。应用程序对 CPU的控制最终由操作系统来管理,如果操作系统发现一个应用程序长时间占用 CPU,那么用户有权终止这个任务。

3.普通函数创建Goroutine

3.1 创建语法

使用go关键字创建Goroutine时,被调用的函数往往没有返回值,如果有返回值也会被忽略。如果需要在Goroutine中返回数据,必须使用channel,通过channel把数据从Goroutine中作为返回值传出。

// 创建Goroutine
go funcName()
3.2 使用
package main
import (
 "fmt"
 "strconv"
 "time"
)
func main() {
 go echoNum("张三")
 go echoNum("李四")
 go echoNum("王五")
 // 睡眠1秒
 time.Sleep(1 * time.Second)
 fmt.Println("运行结束")
}
// 报数
func echoNum(who string)  {
 for i := 1; i < 3; i++ {
  fmt.Println(who + " "+ strconv.Itoa(i))
 }
}

/** 输出
  张三 1
  张三 2
  王五 1
  李四 1
  李四 2
  王五 2
  运行结束
*/

4. 匿名函数创建Goroutine

4.1 创建语法
go func(){
  // ...函数体
}()
4.2 使用
package main
import (
 "fmt"
 "strconv"
 "time"
)
func main() {
 go func(who string) {
  for i := 1; i < 3; i++ {
   fmt.Println(who + " "+ strconv.Itoa(i))
  }
 }("张三")
 go func(who string) {
  for i := 1; i < 3; i++ {
   fmt.Println(who + " "+ strconv.Itoa(i))
  }
 }("李四")
 go func(who string) {
  for i := 1; i < 3; i++ {
   fmt.Println(who + " "+ strconv.Itoa(i))
  }
 }("王五")
 // 睡眠1秒
 time.Sleep(1 * time.Second)
 fmt.Println("运行结束")
}
/** 输出
  张三 1
  张三 2
  王五 1
  王五 2
  李四 1
  李四 2
  运行结束
*/

多个Goroutine随机调度,打印的结果是数字与字母交叉输出

5. 并发运行性能调整

5.1 设置运行的 cpu 数

为了充分了利用多 cpu 的优势,在Golang程序中,可以通过runtime.GOMAXPROCS() 函数 设置运行的 cpu 数目

  • 使用格式
runtime.GOMAXPROCS( 逻辑CPU)
//逻辑CPU可以通过 runtime.NumCpu()函数获取

这里的逻辑CPU数量可以有如下几种数值:

数值含义示例
< 1不修改任何数值runtime.GOMAXPROCS(0)
= 1单核执行runtime.GOMAXPROCS(1)
> 1多核并发执行runtime.GOMAXPROCS(4) 4核并发执行
  • Go 1.5版本之前,默认使用的是单核心执行。从Go 1.5版本开始,默认执行 runtime.GOMAXPROCS(逻辑CPU数量),让代码并发执行,最大效率地利用CPU。
  • GOMAXPROCS同时也是一个环境变量,在应用程序启动前设置环境变量也可以起到相同的作用。

6.注意事项

  • 所有 Goroutinemain()函数结束时会一同结束。
  • 如果需要在 Goroutine中返回数据,必须使用 channel,通过 channel把数据从 Goroutine中作为返回值传出。
  • 启动多个 Goroutine时,会随机调度。

微信搜索关注【猿码记】查看更多文章。

本文由 mdnice 多平台发布

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值