[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 ...
随机推荐
- 【java】 java 中stop方法终止线程的不良后果
stop()方法属于暴力终止线程的方法,有诸多隐患已经被废弃了. 下面演示的是stop方法会释放锁,造成数据不一致的问题. package com.xwolf.java.thread; /** * C ...
- JavaScript------去掉Array中重复值
转载: http://blog.csdn.net/teresa502/article/details/7926796 代码: // 删除数组中重复数据 function removeDuplElem( ...
- NYOJ467 中缀式变后缀式 【栈】
中缀式变后缀式 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描写叙述 人们的日常习惯是把算术表达式写成中缀式,但对于机器来说更"习惯于"后缀式.关于算术 ...
- webpack2.0简单配置教程
以前习惯用gulp+less来开发项目,由于公司项目用的vue开发的,所以学下webpack这个打包工具.以下是我学习时的笔记,希望给在webpack配置过程中遇到麻烦的朋友一丝帮助. 目前只配置了s ...
- Python 使用正则表达式匹配电子邮箱
如下: In [1]: import re In [2]: email = "1210640219@qq.com" In [3]: regular = re.compile(r'[ ...
- eclipse导入maven项目时报Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources
在用Eclipse IDE for Java EE Developers进行maven项目的开发时,报错Could not calculate build plan: Plugin org.apach ...
- setTimeOut一些注意的地方
for (var i = 0; i < data.length; i++) { var flashID = data[i].ID; //setTimeOut(removeFlashDiv(fla ...
- LNMP一键安装包phpMyAdmin无法正常登录,提示:您的Session已过期,请再次登录。
找到文件: /usr/local/php/etc/php.ini 搜索: session.auto_start = 0 修改为 session.auto_start = 1 保存即可!
- Windows Phone 有关独立存储(一)
private const string foldername = "temp1"; private const string filename = foldername + &q ...
- log file sync 事件(转)
log file sync log file sync等待时间发生在redo log从log buffer写入到log file期间. 下面对log file sync做个详细的解释. 何时发 ...