crystal-chinaChina
  • 文档
  • Github
  • 注册
  • 登录
目录
  • 前言
  • 简介
  • 安装 ➤
    • 包管理
  • 写给 Rubyists ➤
    • 类型
    • 方法
    • 代码块
    • 杂项
    • 性能因素
    • 迁移 Ruby 代码到 Crystal
  • 基础知识
  • 交叉编译
  • 并发原语 ➤
    • 执行上下文(WIP)
    • 并发和并行(比较)

并发和并行(比较)

一部分内容翻译自 https://crystal-lang.org/reference/latest/guides/concurrency.html 有可能一部分信息已经过时了,会随时更正。

我们经常会谈起并行(in parallel)和并发(concurrent),他们其实是两个不同的东西。

一个并发的系统,是指能够处理多个任务的系统,虽然,不一定是同时执行的。

你可以想象自己在厨房做菜,你切一个洋葱,放到油锅里炸的同时,你再切一份番茄。 但是你并没有在同一时间做所有事情,你需要分配你的时间来做上面不同的事情,这是并发。 而并行,则是在同一时间,左手炸洋葱,右手切番茄。

截至这篇文章写作日期(2025年六月),Crystal 已经完成了 execution context 的 RFC 大部分开发,在 Crystal 1.16.3 中,已经可以直接使用类似于 golang 的 M:N 混合线程模型, 但是默认并没有开启,需要通过打开 -Dpreview_mt -Dexecution_context 编译时标记来开启。

在当前 1.X 版本 Crystal 中,除了语言的 GC(Boehm GC)使用单独的一个线程之外, 默认总是使用单线程模式执行,在未来的 2.X 版本中,会默认开启多线程模式。

下面介绍 Crystal 实现 concurrency 的一些基础概念:

§ Fibers

Fiber 的概念,类似于 Erlang/Elixir, go 中轻量级用户线程, 不同于操作系统线程(Thread) 的抢占式( pre-emptive), 它是协作式(cooperative)的。

纤维(Fibers),与线程不同,是协作式的。线程是抢占式的:操作系统可以在任何时候中 断一个线程并开始执行另一个线程

  • 轻量,是因为它可以轻易创建成千上万,而相比较操作系统线程,非常少的开销,它虽然 拥有一个与之关联的 8M 堆栈内存空间(和线程一样的),但是其初始只实际占用 4K 内存空间。

  • 用户线程,是因为它被程序语言自己管理,而不是由操作系统管理它。

  • 协作式,操作系统可以在任何时候中断一个线程并开始执行另一个线程, 而协作式,必须 明确的通知运行时调度器,其可以切换到其他纤程。例如,如果一个协程需要等待 I/O 操作完成, 它会告诉调度器:“你看,我必须等待这个 I/O 操作可用,你可以继续执行其他协程, 并在 I/O 准备好后回来唤醒我。”

Crystal 程序可以创建任意多的 Fiber, Crystal 来确保在合适的时候执行它。


下面是 golang 第一作者,来自 Google 的 Rob Pike 大神 2012 做的 slide 分享及对应视频版本。

Concurrency is not Parallelism 及 油管视频(带字幕)

previous_page执行上下文(WIP)

并发和并行(比较)

next_page没有下一页了
欢迎在评论区留下你的见解、问题或建议

正在预览...
正在读取评论...
Crystal China
admin@crystal-china.org
githubtwittercrystal-lang