Golang:线程 和 协程 的区别

做者:林冠宏 / 指尖下的幽灵git

掘金:juejin.im/user/587f0d…github

博客:www.cnblogs.com/linguanh/编程

GitHub : github.com/af913337456…多线程

腾讯云专栏: cloud.tencent.com/developer/u…并发


目录

  • 前言
  • 协程
  • 协程的特色
    • 第 1第 2
    • 特色中的第 3 和 第 4 点
  • 和线程的总体对比

前言

国庆愉快各位,距离上次发文快两个月了,19年也快结束了。如今的总结更可能是放在了草稿 而没有发出,此次详细分享下在 Go 中,线程和协程的区别及其关系编程语言

协程

协程,英文名Coroutine。但在 Go 语言中,协程的英文名是:gorutine。它经常被用于进行多任务,即并发做业。没错,就是多线程做业的那个做业。函数

虽然在 Go 中,咱们不用直接编写线程之类的代码来进行并发,可是 Go 的协程却依赖于线程来进行。post

下面咱们来看看它们的区别。性能

线程的基础介绍,这里请自行网上搜索文章,由于关于线程的优秀介绍文章已经不少。区块链

协程的特色

这里先直接列出线程的特色,而后从例子中进行解析。

  1. 多个协程可由一个或多个线程管理,协程的调度发生在其所在的线程中。
  2. 能够被调度,调度策略由应用层代码定义,便可被高度自定义实现。
  3. 执行效率高。
  4. 占用内存少。

上面第 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
复制代码

意味着在执行协程A的过程当中,能够随时中断,去执协程行B,协程B也可能在执行过程当中中断再去执行协程A。

看起来协程A 和 协程B 的运行像是线程的切换,可是请注意,这里的 A 和 B 都运行在同一个线程里面。它们的调度不是线程的切换,而是纯应用态的协程调度

关于上述代码中,为何要指定下面两行代码?

runtime.GOMAXPROCS(1)
time.Sleep(time.Second)
复制代码

这须要您去看下 Go 的协程调度入门基础,请看我以前的另一篇调度分析文章:

Go 的协程调度机制

若是不设置 runtime.GOMAXPROCS(1),那么程序将会根据操做系统的 CPU 核数而启动对应数量的 P,致使多个 M,即线程的启动。那么咱们程序中的协程,就会被分配到不一样的线程里面去了。为了演示,故设置数量 1,使得它们都被分配到了同一个线程里面,存于线程的协程队列里面,等待被执行或调度。

协程特色中的第 3 和 第 4 点。

  1. 执行效率高。
  2. 占用内存少。

由于协程的调度切换不是线程切换,而是由程序自身控制,所以,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优点就越明显。调度发生在应用态而非内核态。

内存的花销,使用其所在的线程的内存,意味着线程的内存能够供多个协程使用。

其次协程的调度不须要多线程的锁机制,由于只有一个线程,也不存在同时写变量冲突,因此执行效率比多线程高不少。

和线程的总体对比

比较的点 线程 协程
数据存储 内核态的内存空间 通常是线程提供的用户态内存空间
切换操做 操做最终在内核层完成,应用层须要调用内核层提供的 syscall 底层函数 应用层使用代码进行简单的现场保存和恢复便可
任务调度 由内核实现,抢占方式,依赖各类锁 由用户态的实现的具体调度器进行。例如 go 协程的调度器
语音支持程度 绝大部分编程语言 部分语言:Lua,Go,Python ...
实现规范 按照现代操做系统规范实现 无统一规范。在应用层由开发者实现,高度自定义,好比只支持单线程的线程。不一样的调度策略,等等

我的广告

本人技术书籍《区块链以太坊DApp开发实战》现已出版并可网购了,适合初中级区块链技术相关研发人员阅读。