go 协程问题

2017-10-31 22:51:24 +08:00
 ray1888

刚刚接触 go 语言,想请问一个问题,go routine 是如何在后台可以完成耗时的任务而不阻塞当前的任务的呢?

像 python 的 Tornado 可以使用 Thread.Exector 来进行调度,等这个协程跑完之后可以切换到新建的线程池中来进行耗时的操作的处理,也可以使用 asyncio 里面,先把协程任务跑完,然后在最后的事件循环中添加任务来让耗时任务运行。

求 go 语言的高手们解答一下。

4172 次点击
所在节点    程序员
13 条回复
ryd994
2017-10-31 23:38:34 +08:00
举个例子,对于 socket,用 select
你自己写 select 也是一个效果,但是 go 把这个机制做到运行环境里,再用语法糖使得这个流程就像线程一样易于理解和开发
你可以看看这个视频 <amp-youtube data-videoid="MCs5OvhV9S4" layout="responsive" width="480" height="270"></amp-youtube>
changwei
2017-11-01 02:56:41 +08:00
你说的那种如何实现就得看 go 源码了。
传统的 c 语言,python,创建线程要经历 new threadclass,start 等操作,并且 c 语言下还需要进行函数参数的结构体封装,python 因为有 gil 锁,导致其线程无法充分利用多核 cpu。
而 go 创建线程(实际上是 goroutine 协程)只需要在函数前面加一个 go 关键词,并且底层运行时环境会自动根据系统 cpu 核心来调度 goroutine,不存在线程创建过多之后带来线程切换的性能损失。把并发程序的开发简化了很多。
halfer53
2017-11-01 03:36:37 +08:00
go 自身有一个调度器,当其中一个协程调用 blocking syscall,比如 read,go 的调度器回自动检测到,并把同一 socket 下的其他协程切换到其他 socket 去。等 syscall 完成以后,再恢复原状
halfer53
2017-11-01 03:37:55 +08:00
我说的 socket 指的是多核 cpu 下的每一个核
janxin
2017-11-01 07:26:12 +08:00
lz 是否只用过 python 或者只了解过 python 的并发编程?建议从几种常见的并发编程模型入手更容易理解
araraloren
2017-11-01 09:00:19 +08:00
建议你看看这一篇文章,那得根据耗时的任务类型区别对待。。
https://studygolang.com/articles/2357
ray1888
2017-11-01 09:22:57 +08:00
@janxin 因为 python 会用得比较多,以前大学学的 java 和 c++都太久没用,所以现在思路主要是以 python 为主
ray1888
2017-11-01 09:23:24 +08:00
@ryd994 能直接把视频链接放上来吗?你之前烤的那个视频挂掉了
ZSeptember
2017-11-01 09:47:17 +08:00
你看操作系统怎么同时完成多个任务的,当然在微观上同时执行的只有几个任务。
Go 就是这样实现的,Go 的 runtime 实现了一个类似于操作系统的调度器,然后编译器在在函数调用或者什么其他的地方插入一下检查函数,如果 go routine 执行时间过长,就抢占了,执行其他任务
IO 最终都会是系统调用,在系统调用的入口处理一下,就可以使用系统提供的 epoll 之类的了
alexsunxl
2017-11-01 09:50:25 +08:00
@ray1888 视频没挂,youtube 的
ray1888
2017-11-01 09:51:06 +08:00
@alexsunxl 挂上$$之后就看到了,谢谢
zts1993
2017-11-01 09:52:27 +08:00
主要两种
io 类自动转为 non-blocking,epoll trigger 之后恢复 context,继续执行之前的 goroutine
syscall 类的,超时之后会吧队列中其他待执行的移到另一个新 thread 中运行。

可以了解一下 golang M P G
HarrisonZ
2017-11-01 14:03:38 +08:00
golang 官网的文档先看看吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/402414

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX