老师,我有一个很疑惑的地方,关于【goroutine】和【coroutine】

来源:10-2 go语言的调度器

ericdemon

2021-04-14

老师,我学习了协程后有几个疑问想来咨询一下,

    1. coroutine是协程,而goroutine只是Golang里特有的一种协程吗?
    1. coroutine和goroutine之间的区别仅仅是在运行模式上的区别吗?(在我之前学习的网络知识中协程(coroutine)是【单线程顺序执行的】,就是在视频中提到的【非抢占式,需要协程自己交出主动权】,但Golang中的协程goroutine我感觉更多的是一种【抢占式的】【可并行执行的】“强化版”协程。。)
    1. 这也是从我自己的项目中产生的疑问:
      图片描述

         图中的左边的内容是项目中的商品下单的流程图,图中右边的内容是我对协程A和协程B在这一个线程里的运作流程的理解
      
    • 3.1 主要疑问在图中右边的红框内,Golang的协程(goroutine)在面对2个协程都处于阻塞的情况下,系统会来回不断的把当前协程的控制权交出,然后转让给另外的协程吗?
      • 3.1.1 如果真的是我想的那样来回切换协程的话,那发出去的api请求,由于程序被阻塞导致不得不交出控制权给其他协程的时候,它的api响应成功了且返回了数据,这个时候是会把数据放进内存里吗?还是说等到该协程重新拥有控制权后再次请求api,那这样不就变为死循环了吗
写回答

2回答

ccmouse

2021-04-17

这是个好问题。我欢迎大家思考后结合项目提出的问题。

有关goroutine和coroutine的区别,我们大可不必纠结。因为coroutine只是一个说法,它并没有一个业界公认的严格定义。比如同学说的,coroutine是单线程执行,但我个人认为它本身只是为了强调它可以单线程执行,并不是必须单线程执行。那么goroutine算不算coroutine,我们就认为,goroutine是coroutine概念在go语言中对应的实现,就可以了。

回到技术本身,抢占或是非抢占,单线程或是多线程,这些都是底层要关心的事。go语言在语言本身在应用层面上并不关心。本身go语言也已经从单线程非抢占,发展到现在的多线程抢占式。

所以上图右边,传统协程和goroutine,两个框图是一样的。都应该是右边那个。而且交出控制权发生在阻塞的时候,阻塞结束应该是获得控制权。

3.1 主要疑问在图中右边的红框内,Golang的协程(goroutine)在面对2个协程都处于阻塞的情况下,系统会来回不断的把当前协程的控制权交出,然后转让给另外的协程吗?

阻塞了就交出了,那两个都阻塞了就给第三个。没有第三个,操作系统就把你这个进程进入阻塞态,让其他的进程来运行。

阻塞结束是一个被动的机制,等到请求返回,操作系统会知道,然后唤醒你的进程,go运行环境又会把相应的goroutine调度来运行。在请求返回之前它们都不会占用资源,来回切换等。

1
3
ccmouse
回复
ericdemon
我的印象中我一直把因io操作而造成的goroutie切换归位非抢占式。同学是在哪里看到我说这是抢占式的?协程在遇到io阻塞的时候都会交出控制权,是的。
2021-04-23
共3条回复

ericdemon

提问者

2021-04-14

老师,我写的内容可能比较多,真的麻烦您啦

0
1
尼克2018
大致结合老师的解释,更好的理解这一块了。
2022-02-13
共1条回复

Google资深工程师深度讲解Go语言 由浅入深掌握Go语言

语法+分布式爬虫实战 为转型工程师量身打造

5995 学习 · 1909 问题

查看课程