[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 ...
随机推荐
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(一)
题外话:本篇是对之前那篇的重排版.并拆分成两篇,免得没了看的兴趣. 前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的 ...
- 浅谈无缓存I/O操作和标准I/O文件操作差别
首先,先略微了解系统调用的概念: 系统调用,英文名system call,每一个操作系统都在内核里有一些内建的函数库,这些函数能够用来完毕一些系统系统调用把应用程序的请求传给内核,调用对 ...
- 工作流JBPM_day01:6-执行流程实例
工作流JBPM_day01:6-执行流程实例 执行流程 启动流程实例 查询任务列表 办理任务 向后执行一步 先部署流程定义在启动流程实例 Jbpm4_execution表表示正在执行的流程实例的的信息 ...
- swift--触摸(UITouch)事件(点击,移动,抬起)
触摸事件: UITouch:一个手机第一次点击屏幕,会形成一个UITouch对象,知道离开销毁.表示触碰.UITouch对象能表明当前手指触碰的屏幕位置.状态,状态分为开始触碰.移动.离开. 具体方法 ...
- linux--解决oracle sqlplus 中上下左右backspace不能用
1. 解决不能backspace 方法1: stty erase ^h 在oracle用户下:在用户环境配置文件.bash_profile中加入如下语句 stty erase ^h 方法2:在sec ...
- shell基础篇(五)条件判断
写脚本时:有时要判断字符串是否相等,数字测试.这对后面学习的shell语句,循环,条件语句做好基础. 条件判断格式 1. test condition : test命令 2. [ conditio ...
- docker tag 详解
docker tag 用于给镜像打标签,语法如下: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] ① 比如我现在有一个 centos 镜像: [ro ...
- Android中Bitmap和Drawable详解
一.相关概念 1.Drawable就是一个可画的对象,其可能是一张位图(BitmapDrawable),也可能是一个图形(ShapeDrawable),还有可能是一个图层(LayerDrawable) ...
- php 数据库练习之租房子
题目: 示例图 本次只做图4这个表,因为之前的都已做过 自己在mydb数据库建了一个house表 如图: 自己做的代码: <!DOCTYPE html PUBLIC "-//W3C// ...
- java基础---->Java关于复制的使用(一)
这里简单记录一下java中关于浅复制和深复制的知识.很多时候,一个人选择了行走,不是因为欲望,也并非诱惑,他仅仅是听到了自己内心的声音. java中的复制clone方法 一.java对象的浅复制 一个 ...