Posted linguanh
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang:线程 和 协程 的区别相关的知识,希望对你有一定的参考价值。
目录
第 1第 2
前言
草稿线程和协程的区别及其关系
协程
Coroutinegorutine多任务并发作业多线程
依赖于线程
下面我们来看看它们的区别。
线程的基础介绍,这里请自行网上搜索文章,因为关于线程的优秀介绍文章已经很多。
协程的特点
这里先直接列出线程的特点,然后从例子中进行解析。
协程的调度
第 1第 2
我们来看一个例子:
func TestGorutine(t *testing.T)
runtime.GOMAXPROCS(1) // 指定最大 P 为 1,从而管理协程最多的线程为 1 个
wg := sync.WaitGroup // 控制等待所有协程都执行完再退出程序
wg.Add(2)
// 运行一个协程
go func()
fmt.Println(1)
fmt.Println(2)
fmt.Println(3)
wg.Done()
()
// 运行第二个协程
go func()
fmt.Println(65)
fmt.Println(66)
// 设置个睡眠,让该协程执行超时而被挂起,引起超时调度
time.Sleep(time.Second)
fmt.Println(67)
wg.Done()
()
wg.Wait()
顺序是交错
65
66
1
2
3
67
随时中断
纯应用态的协程调度
关于上述代码中,为什么要指定下面两行代码?
runtime.GOMAXPROCS(1)
time.Sleep(time.Second)
这需要您去看下 Go 的协程调度入门基础,请看我之前的另外一篇调度分析文章:
runtime.GOMAXPROCS(1)分配到不同的线程
协程特点中的第 3 和 第 4 点。
- 执行效率高。
- 占用内存少。
协程的调度切换不是线程切换没有线程切换的开销
内存的花销,使用其所在的线程的内存,意味着线程的内存可以供多个协程使用。
不需要多线程的锁机制不存在同时写变量冲突
和线程的整体对比
比较的点 | 线程 | 协程 |
---|---|---|
数据存储 | 内核态的内存空间 | 一般是线程提供的用户态内存空间 |
切换操作 | 操作最终在内核层完成,应用层需要调用内核层提供的 syscall 底层函数 | 应用层使用代码进行简单的现场保存和恢复即可 |
任务调度 | 由内核实现,抢占方式,依赖各种锁 | 由用户态的实现的具体调度器进行。例如 go 协程的调度器 |
语音支持程度 | 绝大部分编程语言 | 部分语言:Lua,Go,Python ... |
实现规范 | 按照现代操作系统规范实现 | 无统一规范。在应用层由开发者实现,高度自定义,比如只支持单线程的线程。不同的调度策略,等等 |
以上是关于Golang:线程 和 协程 的区别的主要内容,如果未能解决你的问题,请参考以下文章