并发入门实战:通过 Exercism Elixir 的 Take-a-Number 系列理解进程、PID 与 GenServer
并发入门实战通过 Exercism Elixir 的 Take-a-Number 系列理解进程、PID 与 GenServer【免费下载链接】elixirExercism exercises in Elixir.项目地址: https://gitcode.com/gh_mirrors/elixi/elixir摘要想在实战中理解 Elixir 并发编程的核心概念Exercism 的 Take-a-Number 系列练习正是为此而生。本文将通过「排队叫号机」这一贴近生活的场景带你一步步掌握Elixir 进程的创建、PID的本质、进程间消息传递以及如何用 OTP 的GenServer优雅地管理并发状态。无论你是 Elixir 新手还是想补全并发知识体系的学习者这份实战指南都能帮你建立从裸进程到 GenServer 的完整认知链路。为什么用「排队叫号机」来学习 Elixir 并发银行、医院里的叫号机本质上是一个有状态的服务进程它记住当前发到几号每次叫号递增还能支持重置。这个模型与 Elixir 的进程模型几乎一一对应叫号机 一个 Elixir 进程顾客手里的号码 进程之间的消息当前号码 进程内部维护的状态Exercism Elixir 官方仓库中exercises/concept/take-a-number/与exercises/concept/take-a-number-deluxe/两个练习构成了完美的进阶路线前者让你手写全部并发原语后者让你用OTP 的 GenServer重写同样的逻辑。同样的业务两种实现对比学习的效果远胜死记硬背。对比维度take-a-numbertake-a-number-deluxe进程创建spawn/1手动创建GenServer.start_link/3消息处理手写receive循环handle_call/handle_cast/handle_info状态管理递归参数传递GenServer 内置状态难点等级⭐ 入门⭐⭐ 进阶第一步用 spawn 创建 Elixir 进程并理解 PID在exercises/concept/take-a-number/lib/take_a_number.ex中你的第一个任务测试文件take_a_number_test.exs的 task 1是实现start/0返回一个新的进程标识符PID。Elixir 中所有代码都运行在进程里spawn/1可以显式地在全新进程中执行函数pid spawn(fn - :ok end) # #PID0.125.0这里的关键认知有三点PID 就是进程的邮箱地址——只要拿到 PID就能向该进程投递消息对应概念文档concepts/pids/introduction.mdElixir 进程极其轻量——它不是操作系统进程内存和 CPU 开销都极小一个应用跑成百上千个进程毫无压力每个进程都有独立的邮箱——消息先进入邮箱排队只有进程主动receive才会被取出见concepts/processes/introduction.md。测试会校验is_pid(pid)、pid ! self()确保你返回的是其他新进程的 PID而不是当前进程。第二步Elixir 进程间通信的核心——send 与 receive 消息传递掌握了 PID 之后第二步就是用send/2和receive/1让进程真正说话。take-a-number 的 task 2 要求实现收到{:report_state, sender_pid}消息后把当前号码发回给发送者。send(pid, {:report_state, self()}) # 发消息报告你的状态 receive do number - number # 收到回复 end而进程内部则用receive/1模式匹配邮箱里的消息receive do {:report_state, sender_pid} - send(sender_pid, current_number) :stop - exit(:normal) end理解这条消息传递链路就理解了 Elixir 并发的全部秘密——进程之间不共享内存只交换消息。想收到回复就必须把发送者的 PIDself()放进消息里这是 Elixir 消息传递最经典的习惯用法。第三步用 receive 循环维护进程状态光能收发一次消息还不够叫号机必须持续服务。task 3 要求连续发出 1、2、3、4、5……这需要进程在receive之后递归调用自己把新的号码作为参数传入下一轮——这就是经典的receive loop模式def loop(current_number) do receive do {:report_state, sender_pid} - send(sender_pid, current_number) loop(current_number) # 状态不变继续循环 {:take_a_number, sender_pid} - send(sender_pid, current_number 1) loop(current_number 1) # 状态递增继续循环 :stop - :ok # 退出循环进程结束 end end状态不放在变量里原地修改而是作为递归参数不断传递——这是函数式并发的精髓。task 4 和 task 5 还会要求你处理:stop消息优雅退出并忽略未知消息比如有人对叫号机喊我要找经理 保证进程不被意外消息搞崩溃。第四步从裸进程升级到 GenServer——OTP 行为实战手写 receive loop 能帮你理解原理但生产级 Elixir 项目几乎都用GenServergeneric server通用服务器来封装这套模式。它本质上就是把你手写的 receive loop 抽象成了可复用的行为behaviour概念细节见concepts/genserver/introduction.md。在exercises/concept/take-a-number-deluxe/lib/take_a_number_deluxe.ex中练习给出了完整的客户端 API 骨架start_link/1—— 启动进程对应init/1回调report_state/1—— 查询状态同步handle_callqueue_new_number/1—— 取新号同步handle_callserve_next_queued_number/2—— 叫号支持优先号同步handle_callreset_state/1—— 重置叫号机异步handle_cast你需要实现的正是三个核心回调回调对应客户端函数语义典型返回值init/1start_link/1初始化状态{:ok, state}handle_call/3call/2系函数同步请求需要回复{:reply, reply, state}handle_cast/2cast/2系函数异步请求无需回复{:noreply, state}handle_info/2直接send/2处理任意消息{:noreply, state}状态则用结构体封装在exercises/concept/take-a-number-deluxe/lib/take_a_number_deluxe/state.ex中min_number、max_number、queue号码队列实现见同目录下的queue.ex、auto_shutdown_timeout自动关闭超时。deluxe 版还藏着一个进阶彩蛋——超时自动关闭init/1返回{:ok, state, timeout}后若指定毫秒数内没有消息到达进程会自动触发handle_info(:timeout, state)实现自我回收。这是 GenServer 回调返回三元组的一个绝佳实战案例。实践指南3 步跑通 Take-a-Number 系列练习获取练习源码git clone https://gitcode.com/gh_mirrors/elixi/elixir进入exercises/concept/take-a-number/目录阅读测试驱动开发先看test/take_a_number_test.exs每个测试都标注了task_id按 1→5 的顺序逐个实现lib/take_a_number.ex中的函数运行测试验证在练习目录执行mix test绿灯全亮后再挑战 deluxe 版本take-a-number-deluxe/体会 GenServer 如何把同样逻辑写得更加清晰。总结一条通往 Elixir 并发的完整学习路径通过 Take-a-Number 系列你实际上完成了一次从底层到框架的完整进阶✅ 用spawn创建Elixir 进程理解PID作为邮箱地址的本质✅ 用send/receive完成进程间消息传递✅ 用receive loop 递归维护进程状态✅ 用GenServer封装状态与消息处理掌握 OTP 行为三件套handle_call/handle_cast/handle_info当你能用两种方式实现同一台叫号机Elixir 的并发模型就已经不再是抽象概念而是你信手拈来的实战技能了。下一步不妨把 take-a-number-deluxe 的队列换成Task或Agent再实现一遍——并发世界的大门正为你敞开。【免费下载链接】elixirExercism exercises in Elixir.项目地址: https://gitcode.com/gh_mirrors/elixi/elixir创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

打造专属短信界面:Simple SMS Messenger 主题、颜色、字体与图标个性化指南

打造专属短信界面:Simple SMS Messenger 主题、颜色、字体与图标个性化指南

打造专属短信界面:Simple SMS Messenger 主题、颜色、字体与图标个性化指南 【免费下载链接】Simple-SMS-Messenger An easy and quick way of managing SMS and MMS messages without ads. 项目地址: https://gitcode.com/gh_mirrors/si/Simple-SMS-Messenger …

2026/9/26 15:43:29 阅读更多 →
5分钟快速上手BeetleX.FastHttpApi:从零搭建你的第一个Web API服务

5分钟快速上手BeetleX.FastHttpApi:从零搭建你的第一个Web API服务

5分钟快速上手BeetleX.FastHttpApi:从零搭建你的第一个Web API服务 【免费下载链接】FastHttpApi a lightweight and high-performance http/websocket service component in the dotnet core platform that supports TLS. 项目地址: https://gitcode.com/gh_mirr…

2026/10/4 16:42:57 阅读更多 →
从OpenClaw到MCP:构建企业级AI智能体的工程化实践与自动化测试

从OpenClaw到MCP:构建企业级AI智能体的工程化实践与自动化测试

1. 项目概述:从“薪资焦虑”到“价值锚点”的实践路径 “实践一下这些项目和技术,薪资30不为过吧”——这个标题背后,是无数技术从业者面对市场变化时最真实的焦虑与渴望。它不是一个简单的疑问句,而是一个行动纲领的起点。当我们…

2026/10/17 3:08:01 阅读更多 →

最新新闻

Kimi-K3-DSpark-MLA-NPU部署实战:NPU推理加速从零到生产级完整清单

Kimi-K3-DSpark-MLA-NPU部署实战:NPU推理加速从零到生产级完整清单

【免费下载链接】Kimi-K3-DSpark-MLA-NPU 项目地址: https://ai.gitcode.com/Eco-Tech/Kimi-K3-DSpark-MLA-NPU 点击查看 免费下载 Kimi-K3-DSpark-MLA-NPU 是面向 NPU 推理加速 的 Kimi K3 大模型投机解码草稿模型(Draft Model)&#xff0c…

2026/10/18 3:03:07 阅读更多 →
SINR自适应波束形成器MVDR Matlab仿真:强干扰下阵列信号处理

SINR自适应波束形成器MVDR Matlab仿真:强干扰下阵列信号处理

简介:这是一份用于无线通信与雷达信号处理的自适应波束形成器MATLAB实现,核心算法基于最大信干噪比(SINR)准则,解决阵列天线在强干扰与噪声环境下期望信号接收质量不佳的问题,适合通信工程、信号处理方向的…

2026/10/18 3:03:07 阅读更多 →
使用Windows自带IIS工具搭建FTP服务,详细教程!

使用Windows自带IIS工具搭建FTP服务,详细教程!

这篇教程搭建FTP服务的方式是采用Windows系统自带的IIS工具,核心步骤主要有4个: 1、安装IIS工具; 2、设置开机启动FTP服务; 3、创建FTP用户; 4、配置FTP服务器; 声明一下:搭建FTP建议升级成 Win…

2026/10/18 3:03:07 阅读更多 →
AI PR门禁落地实践:用GitHub Actions搭建结构化代码审查流水线

AI PR门禁落地实践:用GitHub Actions搭建结构化代码审查流水线

上个月我们团队终于把"AI先审、人工再审"这套流程正式固化成了一条CI流水线,跑在GitHub Actions里。前前后后我们改过三版,踩了不少坑,最后发现整个接入过程其实就三个关键动作:触发工作流、让AI返回结构化结论、把结论…

2026/10/18 3:03:07 阅读更多 →
2026年告别Token焦虑:AI API聚合站怎么选,四大顶级平台测评实录

2026年告别Token焦虑:AI API聚合站怎么选,四大顶级平台测评实录

做 AI 应用最让人头疼的莫过于 Token 账单与多平台管理:模型分散在 OpenAI、Anthropic、Google 与各家国产厂商,注册、充值、对账样样费神。API 聚合站正是为此而生的"AI 模型超市"——不需要逐家注册账号,也无需折腾国外信用卡&am…

2026/10/18 3:03:07 阅读更多 →
ODL下发SRv6卡壳?用Expect脚本打通SSH批量配置的最后一公里

ODL下发SRv6卡壳?用Expect脚本打通SSH批量配置的最后一公里

记不清这是第几次被问“ODL能不能直接下发SRv6策略”了,尤其在刚接触OpenDaylight(ODL)的人眼里,控制器有了RESTCONF、NETCONF,批量下发OSPF、BGP这类配置应该是顺手的事。但真在现场跑一次,你会发现理想和…

2026/10/18 3:02:07 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →