Rust对协程的思考
最近和同事聊起来,觉得lua缺乏编译型语言的类型校验功能,还有变量拼写检查之类的,导致线上总是有低级错误出现。比如最近有一个是变量名拼写少了一个字母,导致某功能没开启;还有一个是变量传参时,之前测试多加了一个参数,测试完成后忘记删了,导致参数顺序不对。之前看过有个TypeLua,没想到现在已经不怎么维护了,去搞了Titan-lang,然而Titan也是4个月没动静了。。。
目前也没想到什么好的解决办法,于是顺带看看Rust-lang,开阔一下思路。我最佩服rust这帮人的,是他们有点壮士断腕的勇气,已经写好的runtime和协程,认为和rust的定位不妥,就直接砍掉了。相关的PR在这里,rfcs在这里。rfcs里面关于协程、线程模型的讨论相当到位,我简要翻译一下,权当记录。以下是译文(节译):
背景:线程/任务模型和I/O
很多语言/库会提供任务,任务一般有别于操作系统的原始线程。任务的特性可以按以下几个维度区分:
- 1:1 vs M:N 最根本的问题是一个任务是不是总是对应到一个OS级别的线程(1:1模型),或者是通过用户空间调度器,将任务映射到worker线程上(M:N模型)。有一些内核,比如Windows,支持用户空间调度的1:1模型,结合了这两者的优势。
在M:N模型里,关于任务何时或者是否在worker线程迁移,各自有不同的选择。但是这个模型有个弊端,如果其中一个任务触发了page fault,整个worker线程都会被阻塞。选择合适的worker线程数目是非常困难的,有些框架尝试动态分配线程数,这也会产生额外开销。
- 栈管理。在1:1模型里,任务就是线程,天然具有栈。在M:N模型里,任务可能有他们自己的栈,这里有重要的取舍:
- 分段栈(segmented stacks)允许栈随着时间增长,意味着任务可以有自己的栈,而且依然保持轻量。但是,分段栈有明显的性能问题和复杂度开销。
- 在没有自己的栈的情况下,任务要么无法在工作线程间迁移(例如Java框架里的fork/join),或者只能用CPS(continuation-passing style)实现,即每个阻塞操作都用一个闭包保存自己的工作状态。(CPS一般将用到的栈保存在闭包里)好处是这些任务特别轻量,基本只是闭包的开销。
- 阻塞和I/O支持。在1:1模型里,一个任务可以被任意阻塞而不会影响其他任务,因为每个任务都是一个OS线程。在M:N模型里,OS的阻塞意味着工作线程的阻塞(比如运行较长时间的循环,或者page fault)M:N模型可以用数种方法解决阻塞。在Java的fork/join框架下,是透过动态增减工作线程来实现的。另一种实现,是提供特殊的任务阻塞操作(包括I/O),将阻塞操作化作底层的非阻塞操作,允许底层工作线程继续运行。但是,这种实现只能对显式阻塞起作用,对于循环、page fault之类的就无效了。
Rust的现状
Rust从绿色线程模型(即协程模型)转向了原始线程模型:
- 在Rust的绿色线程模型里,任务是按M:N进行调度,有自己的栈。最初,Rust使用了分段栈,后面改成了预分配的栈,这样Rust的绿色线程就不是轻量级的了。对阻塞的操作下文再叙
- 在Rust的原始线程模型里,任务是1:1的和OS线程匹配的。
(节略)
问题
强制的共同演进:绿色线程模型和原始线程模型必须提供相同的I/O接口,但是有部分接口只会在其中一种模型里有效。比如,轻量级
开销:目前的Rust模型允许运行时将绿色线程模型和原始线程模型混合使用。但是实现上有如下缺点:
- 二进制大小。任意二进制文件里都包含了整个I/O系统的实现,因为他是libstd标准库的一部分。
- 任务局部存储。目前的任务局部存储是可以无缝在原始线程和绿色线程间切换的。但是性能会有影响,即使可以改进,也比直接采用原始的线程局部存储要复杂得多。
- 动态分配和调度。当前的设计下,所有I/O操作都需要动态调度,大部分的内存分配操作也是。但是,绝大部分情况下,
问题重重的I/O交互:
嵌入式的Rust:
维护困难:
Rust对协程的思考的更多相关文章
- flask之分析线程和协程
flask之分析线程和协程 01 思考:每个请求之间的关系 我们每一个请求进来的时候都开一个进程肯定不合理,那么如果每一个请求进来都是串行的,那么根本实现不了并发,所以我们假定每一个请求进来使用的是线 ...
- 协程的原理(Coroutine Theory)
原文链接:https://lewissbaker.github.io/2017/09/25/coroutine-theory This is the first of a series of post ...
- Flask 之分析线程和协程
目录 flask之分析线程和协程 01 思考:每个请求之间的关系 02 threading.local 03 通过字典自定义threading.local 04 通过setattr和getattr实现 ...
- python之协程与IO操作
协程 协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B ...
- [转载]Python 3.5 协程究竟是个啥
http://blog.rainy.im/2016/03/10/how-the-heck-does-async-await-work-in-python-3-5/ [译] Python 3.5 协程究 ...
- [译] Python 3.5 协程究竟是个啥
转自:http://blog.rainy.im/2016/03/10/how-the-heck-does-async-await-work-in-python-3-5/ [译] Python 3.5 ...
- Python 中的进程、线程、协程、同步、异步、回调
进程和线程究竟是什么东西?传统网络服务模型是如何工作的?协程和线程的关系和区别有哪些?IO过程在什么时间发生? 一.上下文切换技术 简述 在进一步之前,让我们先回顾一下各种上下文切换技术. 不过首先说 ...
- 关于协程的学习 & 线程栈默认10M
先看的这篇文章:http://blog.csdn.net/qq910894904/article/details/41699541 以nginx为代表的事件驱动的异步server正在横扫天下,那么事件 ...
- 深入tornado中的协程
tornado使用了单进程(当然也可以多进程) + 协程 + I/O多路复用的机制,解决了C10K中因为过多的线程(进程)的上下文切换 而导致的cpu资源的浪费. tornado中的I/O多路复用前面 ...
随机推荐
- java基础 - 形参和实参,值传递和引用传递
形参和实参 形参:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的. 形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元. 因此,形 ...
- 二维数组中的查找(剑指offer_4)
给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序.给定一个数,判断这个数是否在该二维数组中. Consider the following matrix: [ [1, 4, 7, 11 ...
- [考试反思]1110csp-s模拟测试109:细节
细节...决定成败 T2数组开小,T3long long没开够. 而且其实不止这样,考试结束前15分钟发现了好多低错: T3双向边没开2倍.dfs没递归调用.T2为了调试bitset开20没改(后来改 ...
- DOM介绍以及使用方法
DOM的基本讲解 一.DOM (Document Object Model)文档对象模型 1.有属性有方法 var person = { name:'派大星', fav:function(){ } } ...
- ch-0503
内容来源<算法竞赛进阶指南>date of submission:20191121tags:归排description modelling:你一定玩过八数码游戏,它实际上是在一个3*3的网 ...
- ETCD:HTTP JSON API通过gRPC网关
原文地址:HTTP JSON API through the gRPC gateway etcd v3 使用 gRPC 作为消息协议.etcd项目包括一个基于gRPC的Go客户端和一个命令行工具,et ...
- Python 爬虫从入门到进阶之路(一)
通用爬虫和聚焦爬虫 根据使用场景,网络爬虫可分为 通用爬虫 和 聚焦爬虫 两种. 通用爬虫 通用网络爬虫 是 捜索引擎抓取系统(Baidu.Google.Yahoo等)的重要组成部分.主要目的是将互联 ...
- Java中String直接赋字符串和new String的一些问题
今天课堂测试做了几道String的练习题,做完直接心态爆炸...... 整理自下面两篇博客: https://www.cnblogs.com/marsitman/p/11248001.html htt ...
- 利用 chunked 类型响应实现后台请求的监听
Koa 中实现 chunked 数据传输 中介绍了如何在 Koa 中实现 Transfer-Encoding:chunked 类型的响应分片传输.这里来看一个应用场景. 假如我们想监听后台的请求,并将 ...
- Spring Boot 2 快速教程:WebFlux 快速入门(二)
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 02:WebFlux 快速入门实践 文章工程: JDK 1.8 ...