[golang note] 协程基础
协程概念
√ 协程通常称为coroutine,在golang中称为goroutine。
√ 协程本质上是一种用户态线程,它不需要操作系统来进行抢占式调度,在实际实现中寄存在线程之中。
√ 协程系统开销极小,可有效提高单个线程的任务并发性,从而避免使用多线程。而且使用协程编程简单,结构清晰。缺点就是需要编程语言的支持,如果不支持,则需要用户在程序中自行实现调度器。
goroutine
√ goroutine是golang中的轻量级线程实现,由go runtime管理。
• goroutine使用语法
// 定义协程函数
func MyRoutineFunction(参数列表) (返回值列表) {
// 函数体
} // 启动协程
go MyRoutineFunction(参数列表)
√ 启动一个goroutine使用go关键字,go是golang中最重要的关键字,因此这个语言也是以这个关键字命名。
√ 在一个函数前加上go关键字调用,这次调用就会在一个新的goroutine中并发执行,开启goroutine的线程将继续执行。
√ 当被go调用的函数返回时,这个goroutine也自动结束了。如果这个函数有返回值,那么这个返回值会被丢弃。
√ golang程序从main()函数开始执行,当main()函数返回时,程序结束且不等待其他goroutine结束。
• goroutine使用示例
package main import (
"fmt"
"time"
) func Add(x, y int) {
z := x + y
fmt.Println(z)
} func main() {
for i := ; i < ; i++ {
go Add(i, i)
} fmt.Println("main goroutine finished!")
time.Sleep( * time.Second)
}
程序运行两次的结果如下:

可以看出goroutine看上去的确是并发执行,结果具有不确定性。
并发与并行
• 概念

√ 两个队列,一个Coffee机器,那是并发。
√ 两个队列,两个Coffee机器,那是并行。
• golang并发与并行
▶ 并发执行
√ 如果在单核cpu情况下,golang所有的goroutine只能在一个线程里跑 。
√ 如果当前goroutine不发生阻塞,它是不会让出cpu时间给其他goroutine,除非调用runtime.Gosched()主动让出时间片。
√ 如果当前goroutine发生阻塞,它会主动让出cpu时间给其他goroutine执行。
√ golang的runtime包是goroutine的调度器,其中使用runtime.GOMAXPROCS(n)可以控制使用cpu核数。
▪ 例子一
package main import "fmt"
import "time"
import "runtime" func loop() {
fmt.Println("loop starts!")
for i := ; i < ; i++ {
fmt.Printf("%d ", i)
}
fmt.Println()
} func main() {
runtime.GOMAXPROCS(1) // 强制使用1个cpu
go loop()
go loop() time.Sleep( * time.Second)
}
运行结果如下:

▪ 例子二
package main import (
"fmt"
"runtime"
"time"
) func Add(x, y int) {
z := x + y
fmt.Println(z)
} func main() {
runtime.GOMAXPROCS(1) // 强制使用1个cpu
go Add(, )
go Add(, )
go Add(, )
go Add(, )
go Add(, )
go Add(, )
go Add(, )
go Add(, )
go Add(, )
go Add(, ) fmt.Println("main goroutine finished!")
time.Sleep( * time.Second)
}
运行结果如下:

▶ 并行执行
√ 默认情况下,golang是开启多核的,因此一开始的示例中的输出就是无序的。
√ 我们也可以告诉golang我们允许同时最多使用核数。
▪ 例子一
package main import "fmt"
import "time"
import "runtime" func loop() {
fmt.Println("loop starts!")
for i := ; i < ; i++ {
fmt.Printf("%d ", i)
}
fmt.Println()
} func main() {
runtime.GOMAXPROCS() go loop()
go loop()
go loop()
go loop() time.Sleep( * time.Second)
}
多运行几次,可以得到结果:
[golang note] 协程基础的更多相关文章
- [golang note] 协程通信
channel基本语法 • channel介绍 √ golang社区口号:不要通过共享内存来通信,而应该通过通信来共享内存. √ golang提供一种基于消息机制而非共享内存的通信模型.消息机制认为每 ...
- Golang 之协程详解
转自:https://www.cnblogs.com/liang1101/p/7285955.html 一.Golang 线程和协程的区别 备注:需要区分进程.线程(内核级线程).协程(用户级线程)三 ...
- GoLang之协程
GoLang之协程 目前,WebServer几种主流的并发模型: 多线程,每个线程一次处理一个请求,在当前请求处理完成之前不会接收其它请求:但在高并发环境下,多线程的开销比较大: 基于回调的异步IO, ...
- 在C++中使用golang的协程
开源项目cpp_features提供了一个仿golang协程的stackful协程库. 可以在c++中使用golang的协程,大概语法是这样的: #include <iostream> v ...
- pyhon——进程线程、与协程基础概述
一直以来写博客都是实用主义者,只写用法,没信心写原理,但是每一次写作业的过程都有一种掘地三尺的感觉,终于,写博客困难症重症患者经历了漫长的思想斗争,还是决定把从网上淘到的各种杂货和自己的总结放在一起, ...
- Golang 的 协程调度机制 与 GOMAXPROCS 性能调优
作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...
- golang:协程安全
多路复用 Go语言中提供了一个关键字select,通过select可以监听channel上的数据流动.select的用法与switch语法类似,由select开始一个新的选择块,每个选择条件由case ...
- Kotlin协程基础
开发环境 IntelliJ IDEA 2021.2.2 (Community Edition) Kotlin: 212-1.5.10-release-IJ5284.40 我们已经通过第一个例子学会了启 ...
- Unity协程基础用法
//通过StartCoroutine()开始一个协程//通过StopCoroutine();关闭一个协程//通过StopAllCoroutines()方法来实现关闭所有协程void Start(){D ...
随机推荐
- HTML5 直播技术
https://segmentfault.com/a/1190000010440054
- 二:Java之异常处理
一.异常的概念 异常,也就是非正常情况. 其实.异常本质上是程序上的错误,包含程序逻辑错误和系统错误. 错误在我们编敲代码的过程中会常常发生,包含编译期间和执行期间的错误,在编译期间出现的错误有编译器 ...
- Effective C++ Item 15 Provide access to raw resources in resource-managing classes
In last two item, I talk about resource-managing using RAII, now comes to the practical part. Often, ...
- break、continue、return之间的区别与联系
今天在部署程序的时候,监控日志发现这个问题了.return的问题就这么总结哈. 在软件开发过程中,逻辑清晰是非常之重要的. 代码的规范也是非常重要的.往往细节决定成败.在编写代码的时候,一定要理解语言 ...
- 使用keytool生成密钥对
1.首先要用KeyTool工具来生成私匙库:(-alias别名 –validity 3650表示10年有效) keytool -genkey -alias privatekey -keystore p ...
- Oracle应用技术精华教程:管理还原段
管理还原段 在oracle 9i 之后提供了两种方法来管理还原数据 自动的还原数据管理:oracle 自动管理还原段的创建.分配和优化 手动的还原数据管理:oracle 手动管理还原段的创建.分配和优 ...
- LVS+keeplived+nginx+tomcat高可用、高性能jsp集群
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://kerry.blog.51cto.com/172631/557749 #!/bin ...
- KVO的用法、底层实现原理
KVO的用法 KVO也就是key-value-observing(即键值观察),利用一个key来找到某个属性并监听其值得改变.用法如下: 添加观察者 在观察者中实现监听方法,observeValueF ...
- Linux下Redis集群环境的搭建
一.安装redis(使用redis3.0版本) 1.需要gcc环境,如果没有执行命令安装gcc yum install gcc-c++ 2.下载redis3.0的源码包并上传至服务器 3.解压源码包 ...
- HTTP/2笔记之错误处理和安全
零.前言 这里整理了一下错误和安全相关部分简单记录. 一.HTTP/2错误 1. 错误定义 HTTP/2定义了两种类型错误: 导致整个连接不可使用的错误为连接错误(connection error) ...