网易首页 > 网易号 > 正文 申请入驻

GO、Rust 这些新一代高并发编程语言为何都极其讨厌共享内存?

0
分享至

作者 | 马超 责编 | 王晓曼

出品 | CSDN博客

今天我想再来讨论一下高并发的问题,我们看到最近以Rust、Go为代表的云原生、Serverless时代的语言,在设计高并发编程模式时往往都会首推管道机制,传统意义上并发控制的利器如互斥体或者信号量都不是太推荐。

这里我们先来看一下并发和并行的概念,我们知道并发是一个处理器同时处理多个任务,这里同时是逻辑上的,而并行同一时刻多个物理器同时执行不同指令,这里的同时物理上的。

并发是要尽量在目前正在执行的任务遇到阻塞或者等待操作时,释放CPU,让其它任务得以调度,而并行则是同时执行不同任务而不相互影响。

而传统的信号量、互斥体的设计都是为了让单核CPU发挥出最大的性能,让程序在阻塞时释放CPU,通过控制共享变量的访问来达到避免冲突的目的,而想控制好这些共享变量的行为,其关键因此在于设计好时序,从本质上讲控制时序就是给系统加上红绿灯并配备路障。

这里你一定要记住,高性能系统需要的是立交桥、地下隧道这些基础设施,而不是交通信号等控制手段,好的并发系统一定要用流的概念来建模,而不是到处增加关卡路障。

现在的处理都是多核架构,因此编程也要向并行倾斜,不过笔者在网上看到很多所谓标榜高并发教程中所举的例子,都把信号灯设计的时序很完美,却偏偏把立交桥全给扔了......

图源:CSDN付费下载自视觉中国

信号灯应该为导流服务,而不应为限流而生

下面我们来看三段分别对应信号灯控制的操作,互斥体统治的“并发”,以及单纯的串行的代码,代码的目标其实就是要完成从0一直加到3000000的操作。

信号灯控制

其实这种信号量的代码已经基本退化回了顺序执行的方案了。正如我们在前文《GO看你犯错,但是Rust帮你排坑所说》,Rust的变量生命周期检查机制,并不能支持在不同线程之间共享内存,即便可以曲线救国,也绝非官方推荐,因此这里先用Go带各位读者说明。


package mainimport ("fmt""sync""time")var count intvar wg1 sync.WaitGroupvar wg2 sync.WaitGroupvar wg3 sync.WaitGroupvar wg4 sync.WaitGroupfunc goroutine1() { wg1.Wait()len := 1000000for i := 0; i < len; i++ { count++ } wg2.Done()}func goroutine2() { wg2.Wait()len := 1000000for i := 0; i < len; i++ { count++ } wg3.Done()}func goroutine3() { wg3.Wait()len := 1000000for i := 0; i < len; i++ { count++ } wg4.Done()}func main() { now := time.Now().UnixNano() wg1.Add(1) wg2.Add(1) wg3.Add(1) wg4.Add(1)go goroutine1()go goroutine2()go goroutine3() wg1.Done() wg4.Wait() fmt.Println(time.Now().UnixNano() - now) fmt.Println(count)}

在这里三个子协程goroutine,在4个信号量的控制下以多米诺骨牌的方式依次对于共享变量count进行操作,这段代码的运行结果如下:


49843003000000成功: 进程退出代码 0.

互斥体控制

与信号量完全退化成顺序执行不同,互斥体本质上同一时刻只能有一个goroutine执行到临界代码,但每个goroutine的执行顺序却无所谓,具体如下:


package mainimport ( "fmt" "sync" "time")var count intvar wg1 sync.WaitGroupvar mutex sync.Mutexfunc goroutine1() { mutex.Lock() len := 1000000 for i := 0; i < len; i++ { count++ } mutex.Unlock() wg1.Done()}func main() { now := time.Now().UnixNano() wg1.Add(3) go goroutine1() go goroutine1() go goroutine1() wg1.Wait() fmt.Println(time.Now().UnixNano() - now) fmt.Println(count)}

从运行实序上来看,互斥体的方案应该和信号量差不多,不过结果却令人意,在互斥体的控制下,这个程序性能反而还下降了30%,具体结果如下:


59868003000000成功: 进程退出代码 0.

串行方式:

最后用最返璞归真的做法,串行操作代码如下:


package mainimport ( "fmt" //"sync" "time")var count intfunc goroutine1() { len := 1000000 for i := 0; i < len; i++ { count++ }}func main() { now := time.Now().UnixNano() goroutine1() goroutine1() goroutine1() fmt.Println(time.Now().UnixNano() - now) fmt.Println(count)}

可以看到从效率上来讲,直接串行的方式和信号量的方式是差不多的,结果如下:


49867003000000成功: 进程退出代码 0.

也就是说费了半天劲,最终结果可能还不如直接串行执行呢。

Rust Future初探

Rust中的future机制有点类似于 JavaScript 中的promise机制。Future机制让程序员可以使用同步代码的方式设计高并发的异步场景。目前虽然Go当中也有一些defer的机制,但远没有Rust中的future这么强大。Future机制将返回值value与其计算方式executor分离,从而让程序员可以不再关注于具体时序机制的设计,只需要指定Future执行所需要的条件,以及执行器即可。

我们来看以下代码。

注:cargo.toml


[dependencies]futures = { version = "0.3.5", features = ["thread-pool"] }

代码如下:


use futures::channel::mpsc;use futures::executor;use futures::executor::ThreadPool;use futures::StreamExt;fn main() {let poolExecutor = ThreadPool::new().expect("Failed");let (tx, rx) = mpsc::unbounded::();let future_values = async {let fut_tx_result = async move {let hello = String::from("hello world");for c in hello .chars() {tx.unbounded_send(c.to_string()).expect("Failed to send");poolExecutor.spawn_ok(fut_tx_result);let future_values = rx.map(|v| v).collect();future_values.awaitlet values: Vec = executor::block_on(future_values);println!("Values={:?}", values);

上述代码中我们通过async指定了future_values ,并将这个Future指定给poolExecutor这个线程池执行,最后通过await方法,就可以让future全部执行完毕,而不必再用信号量控制具体的时序。

这样一来,只要深度掌握future机制,就可以不必再关心互斥体、信号量,具体的高度方式完全放心交给计算机去做优化,不但可以节约程序员的时间,也能充分发挥编译器的威力,尾号是避免出现那种扔掉立交桥,只要信号灯低级的错误方式。

Java虽然也有一定的Future实现,并且有Rust不具备的反射能力,但是冷起动一直是困扰Java的痛。因此在目前云原生的时代,Go和Rust尤其是Rust语言以其近首于C语言的启动速度,和运行效率真是很有可能在未来称王。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
中东各国的操作越来越骚,难道他们遇到了菩提祖师?

中东各国的操作越来越骚,难道他们遇到了菩提祖师?

老妖的针见
2024-06-27 13:30:03
黑龙江省发布高温预报 18区县最高温可达37℃

黑龙江省发布高温预报 18区县最高温可达37℃

北青网-北京青年报
2024-07-01 19:17:08
名嘴:除湖人还有快船森林狼太阳猛龙想选布朗尼 被里奇-保罗警告

名嘴:除湖人还有快船森林狼太阳猛龙想选布朗尼 被里奇-保罗警告

直播吧
2024-07-02 04:04:02
彻底倒向美囯?拒绝中方移民,驱离中方工人,中方大怒:永不合作

彻底倒向美囯?拒绝中方移民,驱离中方工人,中方大怒:永不合作

星辰故事屋
2024-04-27 19:04:44
最高法院裁判:没有转账凭证的大额现金借款,如何审查证明标准

最高法院裁判:没有转账凭证的大额现金借款,如何审查证明标准

烟语法明
2024-06-30 23:07:08
中东最大“白眼狼” 王毅才提出建议 立马翻脸 否定中国提议

中东最大“白眼狼” 王毅才提出建议 立马翻脸 否定中国提议

星辰故事屋
2024-06-30 18:31:33
冯莱再次发社媒:上海队总经理助理故意输比赛,扣除我的奖金

冯莱再次发社媒:上海队总经理助理故意输比赛,扣除我的奖金

懂球帝
2024-07-01 15:38:09
形势突变!中国大使馆紧急提醒

形势突变!中国大使馆紧急提醒

半岛官网
2024-06-29 14:26:08
老公外出打工,新婚媳妇和公公住一屋,有了生理反应怎么办?

老公外出打工,新婚媳妇和公公住一屋,有了生理反应怎么办?

户外阿崭
2024-06-25 09:06:41
巴菲特预言:20年或50年后,日本和美国都将更强大,中国呢?

巴菲特预言:20年或50年后,日本和美国都将更强大,中国呢?

阿握看历史
2024-06-27 09:53:57
突发暴雨,多位明星称家中漏水:陈赫家成“水帘洞”,陈龙在家撑伞

突发暴雨,多位明星称家中漏水:陈赫家成“水帘洞”,陈龙在家撑伞

西湖之声
2024-07-01 18:22:48
15人大交易!独行侠与活塞完成了一笔4换1的交易!

15人大交易!独行侠与活塞完成了一笔4换1的交易!

篮球技巧教学
2024-07-01 14:43:49
半场-葡萄牙0-0斯洛文尼亚 C罗任意球造险两队仅1射正

半场-葡萄牙0-0斯洛文尼亚 C罗任意球造险两队仅1射正

直播吧
2024-07-02 03:54:21
教育部同意:北京,再添一部属大学!

教育部同意:北京,再添一部属大学!

双一流高校
2024-06-29 17:41:27
华为官宣,降价6000元!优惠幅度逐步收窄

华为官宣,降价6000元!优惠幅度逐步收窄

21世纪经济报道
2024-07-01 13:00:10
回顾江苏一老板娘,为学技术不惜以身相报,荒唐情感酿出人命惨案

回顾江苏一老板娘,为学技术不惜以身相报,荒唐情感酿出人命惨案

韩玥故事集
2024-06-26 19:36:14
乌克兰麻烦来了,朝鲜4个旅2万大军开赴前线,战斗素质极强

乌克兰麻烦来了,朝鲜4个旅2万大军开赴前线,战斗素质极强

云端书馆
2024-06-30 07:25:10
事情越闹越大!现场画面曝光,美方直言绝不可接受!中方重磅表态

事情越闹越大!现场画面曝光,美方直言绝不可接受!中方重磅表态

布衣的呼喊
2024-07-01 09:10:03
假学历,假豪门,从头假到脚?“央视名嘴”杨澜丈夫遭全网质疑?

假学历,假豪门,从头假到脚?“央视名嘴”杨澜丈夫遭全网质疑?

史诗长歌
2024-06-24 15:00:03
象棋特级大师王天一接受调查,北大毕业,女友漂亮大方,热衷公益

象棋特级大师王天一接受调查,北大毕业,女友漂亮大方,热衷公益

不如归趣
2024-07-01 15:04:49
2024-07-02 05:36:49
CSDN
CSDN
成就一亿技术人
24761文章数 241834关注度
往期回顾 全部

科技要闻

天兵科技巩义现场工作人员:正寻找黑匣子

头条要闻

欧洲杯-法国1-0比利时晋级8强 维尔通亨自摆乌龙

头条要闻

欧洲杯-法国1-0比利时晋级8强 维尔通亨自摆乌龙

体育要闻

他们距离创造历史,只差1分33秒

娱乐要闻

今年内娱最大的闹剧,该收场了

财经要闻

债牛疯狂不止,引央行“出手”!

汽车要闻

奥迪Q6 e-tron Sportback官图曝光

态度原创

本地
教育
数码
游戏
健康

本地新闻

冷知识:东北雪糕才是最早的网红雪糕

教育要闻

学霸解了半天,到最后还是放弃了,有根号难度大

数码要闻

七彩虹多款 Z890、B860、H810 及技嘉 X870 主板现身 EEC 认证

钢岚:测试服最终版调整汇总分析!这样的艾琳专武满意了么?

人类为何至今无法攻克渐冻症?

无障碍浏览 进入关怀版