Elixir学习笔记——进程(Processes)

在 Elixir 中,所有代码都在进程内运行。进程彼此隔离,彼此并发运行并通过消息传递进行通信。进程不仅是 Elixir 中并发的基础,而且还提供了构建分布式和容错程序的方法。

Elixir 的进程不应与操作系统进程混淆。Elixir 中的进程在内存和 CPU 方面非常轻量级(甚至与许多其他编程语言中使用的线程相比也是如此)。因此,同时运行数万甚至数十万个进程并不罕见。

在本章中,我们将学习生成新进程的基本构造,以及在进程之间发送和接收消息。

生成进程

生成新进程的基本机制是自动导入的 spawn/1 函数:

spawn/1 接受一个函数,它将在另一个进程中执行。

注意 spawn/1 返回一个 PID(进程标识符)。此时,您生成的进程很可能已死。生成的进程将执行给定的函数,并在函数完成后退出:

注意:您可能会获得与我们在代码片段中显示的不同进程标识符。

我们可以通过调用 self/0 来检索当前进程的 PID:

当我们能够发送和接收消息时,进程会变得更加有趣。

发送和接收消息

我们可以使用 send/2 向进程发送消息,并使用 receive/1 接收消息:

当消息发送到进程时,该消息存储在进程邮箱中。receive/1 块会遍历当前进程邮箱,搜索与任何给定模式匹配的消息。receive/1 支持保护和许多子句,例如 case/2。

发送消息的进程不会在 send/2 上阻塞,它会将消息放入收件人的邮箱并继续。特别是,进程可以向自己发送消息。

如果邮箱中没有与任何模式匹配的消息,则当前进程将等待,直到匹配的消息到达。还可以指定超时:

当您已经预计消息在邮箱中时,可以指定 0 的超时。

让我们将所有内容放在一起并在进程之间发送消息:

inspect/1 函数用于将数据结构的内部表示转换为字符串,通常用于打印。请注意,当执行接收块时,我们生成的发送方进程可能已经死亡,因为它的唯一指令是发送消息。

在 shell 中,您可能会发现辅助程序 flush/0 非常有用。它会刷新并打印邮箱中的所有消息。

链接

大多数情况下,我们在 Elixir 中生成进程时,都会将它们生成为链接进程。在展示 spawn_link/1 的示例之前,让我们看看当使用 spawn/1 启动的进程失败时会发生什么:

它只是记录了一个错误,但父进程仍在运行。这是因为进程是孤立的。如果我们希望一个进程中的失败传播到另一个进程,我们应该将它们链接起来。这可以通过 spawn_link/1 完成:

由于进程是链接的,我们现在看到一条消息,表示父进程(即 shell 进程)已收到来自另一个进程的 EXIT 信号,导致 shell 终止。IEx 检测到这种情况并启动新的 shell 会话。

也可以通过调用 Process.link/1 手动完成链接。我们建议您查看 Process 模块以了解进程提供的其他功能。

进程和链接在构建容错系统时起着重要作用。Elixir 进程是独立的,默认情况下不共享任何内容。因此,进程中的故障永远不会崩溃或破坏另一个进程的状态。但是,链接允许进程在发生故障时建立关系。我们经常将进程链接到主管,主管将检测进程何时死亡并代替其启动新进程。

虽然其他语言会要求我们捕获/处理异常,但在 Elixir 中,我们实际上可以允许进程失败,因为我们希望监督者能够正确重新启动我们的系统。“快速失败”(有时称为“让它崩溃”)是编写 Elixir 软件时的常见理念!

spawn/1 和 spawn_link/1 是 Elixir 中创建进程的基本原语。虽然到目前为止我们只使用它们,但大多数时候我们将使用在它们之上构建的抽象。让我们看看最常见的一个,称为任务。

任务

任务建立在 spawn 函数之上,以提供更好的错误报告和自省:

我们使用 Task.start/1 和 Task.start_link/1 而不是 spawn/1 和 spawn_link/1,它们返回 {:ok, pid} 而不仅仅是 PID。这使得任务可以在监督树中使用。此外,Task 提供了便利函数,如 Task.async/1 和 Task.await/1,以及简化分发的功能。

我们将在“Mix 和 OTP 指南”中探索围绕流程的任务和其他抽象。

状态

到目前为止,我们还没有讨论过状态。如果您正在构建一个需要状态的应用程序,例如,保存应用程序配置,或者您需要解析文件并将其保存在内存中,您会将其存储在哪里?

进程是这个问题最常见的答案。我们可以编写无限循环、保持状态以及发送和接收消息的进程。作为示例,让我们编写一个模块,该模块启动新进程,这些进程在名为 kv.exs 的文件中作为键值存储:

请注意,start_link 函数启动一个运行 loop/1 函数的新进程,从一个空映射开始。然后,loop/1(私有)函数等待消息并对每条消息执行适当的操作。我们使用 defp 而不是 def 将 loop/1 设为私有。对于 :get 消息,它会将消息发送回调用者并再次调用 loop/1,以等待新消息。而 :put 消息实际上使用新版本的映射调用 loop/1,并存储给定的键和值。

让我们通过运行 iex kv.exs 来尝试一下:

首先,进程图没有键,因此发送 :get 消息然后刷新当前进程收件箱将返回 nil。让我们发送 :put 消息并重试:

请注意进程如何保持状态,我们可以通过发送进程消息来获取和更新此状态。事实上,任何知道上述 pid 的进程都可以向其发送消息并操纵状态。

还可以注册 pid,为其命名,并允许知道该名称的每个人都向其发送消息:

使用进程来维护状态和名称注册是 Elixir 应用程序中非常常见的模式。但是,大多数时候,我们不会像上面那样手动实现这些模式,而是使用 Elixir 附带的众多抽象之一。例如,Elixir 提供了 Agents,它们是围绕状态的简单抽象。我们上面的代码可以直接写成:

还可以为 Agent.start_link/2 提供 :name 选项,它将自动注册。除了代理之外,Elixir 还提供了用于构建通用服务器(称为 GenServer)、注册表等的 API,所有这些都由底层进程提供支持。这些以及监督树将在“Mix 和 OTP 指南”中进行更详细的探讨,该指南将从头到尾构建一个完整的 Elixir 应用程序。

现在,让我们继续探索 Elixir 中的 I/O 世界。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/853130.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进程的创建和管理

一. 实验内容 1. 编写一个程序,程序中创建一个子进程。然后父、子进程各自独立运行,父进程不断地在标准输出设备(即显示器)上输出字母p和回车(输出30次或以上),子进程不断地在标准输…

[面试题]Java【并发】

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL 因为 Java 并发涉及到的内容会非常多,本面试题可能很难覆盖到所有的知识点,所以推荐 《Java并发编程的艺术》 。 Java 线程 线程 通知 等待 线…

植物ATAC-seq文献集锦(三)——果实发育篇

ATAC-seq在植物研究领域的应用我们已经介绍2期了,本期我们聚焦ATAC-seq技术在果实发育方向的应用案例。 植物ATAC-seq文献集锦(一)——基因组篇 植物ATAC-seq文献集锦(二)——生长发育篇 文献一:Ident…

Linux 内核 (十二)进程间通讯 之 消息队列

前言 这个系列的上一篇介绍了进程间通讯关于管道相关的内容及代码实例,本章要介绍关于消息队列相关的内容. 消息队列交互图示 函数原型 #include <sys/msg.h> #include <sys/ipc.h> //创建 or 打开队列 成功返回队列ID,失败返回-1 int msgget(key_t key,int fla…

商城小程序系统:一站式搭建,轻松上线

前言 近年来&#xff0c;商城小程序系统以其便捷、高效的特点&#xff0c;正逐渐成为商品买卖的新宠。这类小程序&#xff0c;类似于我们熟知的京东、淘宝等电商巨头&#xff0c;为商家提供了一个全新的销售渠道&#xff0c;让商品买卖更加智能化、便捷化。 一、商城小程序有什…

【Linux】从零开始配置新的服务器的机器学习环境

终端远程登录 ssh -p [端口号] [服务器用户名][服务器IP]或者 ssh [用户名][主机地址]第二种的前提是在.ssh\config中配置了host 安装文本编辑器vim 主要用于后续的文本编辑&#xff0c;个人比较习惯用vim&#xff0c;根据自己喜好选择 更新apt sudo apt update安装文本编辑…

MyBatis使用 PageHelper 分页查询插件的详细配置

1. MyBatis使用 PageHelper 分页查询插件的详细配置 文章目录 1. MyBatis使用 PageHelper 分页查询插件的详细配置2. 准备工作3. 使用传统的 limit 关键字进行分页4. PageHelper 插件&#xff08;配置步骤&#xff09;4.1 第一步&#xff1a;引入依赖4.2 第二步&#xff1a;在m…

在VMware中安装CentOS7(超详细的图文教程)

1、CentOS7的下载 官网下载地址&#xff1a;Download。 进入CentOS下载官网&#xff0c;找到64位的CentOS7版本。 点进来后&#xff0c;发现它给我们列出了所在区域可用镜像源&#xff08;可以说是非常的良心的&#xff09;&#xff0c;我们随便选择一个&#xff0c;这里以阿…

面向对象编程垃圾回收机制

系列文章目录 文章目录 系列文章目录前言一、垃圾回收机制&#xff08;Garbage Collection&#xff09; 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用…

Python保姆级教程 数据类型—新手小白入门必看

python学习资料&#xff0c;下方已打包好 一、基本数据类型与变量&#xff08;上&#xff09; 2.1 注释 优点&#xff1a; 代码说明 没注释的代码 有注释的代码 不让解释器执行注释的那句话 2.2 单行注释 单行注释快捷键&#xff1a;ctrl &#xff1f; 2.3多行注释 …

leetcode刷题记录42-1584. 连接所有点的最小费用

问题描述 给你一个points 数组&#xff0c;表示 2D 平面上的一些点&#xff0c;其中 points[i] [xi, yi] 。 连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 &#xff1a;|xi - xj| |yi - yj| &#xff0c;其中 |val| 表示 val 的绝对值。 请你返回将所有点连…

U-Mail国产信创邮件系统,让企业通信更加安全可控

信息技术应用创新产业&#xff0c;即信创产业&#xff0c;是信息化建设的核心&#xff0c;它涵盖了从硬件到软件的一系列关键技术。信创产业的目标是通过自主研发&#xff0c;减少对外部技术的依赖&#xff0c;增强信息安全&#xff0c;并提升国内产业的全球竞争力。该产业主要…

如何用Vue3和p5.js打造一个令人惊叹的3D球体在线展示

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 使用 p5.js 创建交互式 3D 图形 应用场景介绍 p5.js 是一个用于创建交互式图形和动画的 JavaScript 库。它被广泛用于教育、艺术和设计领域&#xff0c;让开发者可以轻松创建具有吸引力的可视化效果。 代码基…

什么是堡垒机?和跳板机是一个概念吗?

堡垒机&#xff0c;又称运维审计系统、跳板机&#xff0c;是一种位于内部网络与外部网络之间的安全防护设备&#xff0c;它充当了一个“中间人”的角色&#xff0c;所有对内部网络资源的远程访问都必须通过堡垒机进行。这一设计的核心目的&#xff0c;在于严格控制和记录所有进…

任务3.8.1 利用RDD实现词频统计

实战&#xff1a;利用RDD实现词频统计 目标 使用Apache Spark的RDD&#xff08;弹性分布式数据集&#xff09;模块实现一个词频统计程序。 环境准备 选择实现方式 确定使用Spark RDD进行词频统计。 Spark版本与Scala版本匹配 选择Spark 3.1.3与Scala 2.12.15以匹配现有Spar…

kafka原理简介

Kafka是由LinkedIn开发的一个分布式发布/订阅的消息系统和一个强大的队列&#xff0c;使用Scala编写&#xff0c;它以可扩展和高吞吐率而被广泛使用。 Kafka适合离线和在线消息消费。 Kafka消息保留在磁盘上&#xff0c;并在群集内以master-flower方式实现数据同步&#xff0c;…

用Canvas绘制2D平面近大远小的马路斑马线

用Canvas绘制2D平面近大远小的马路斑马线 设置canvas和上下文&#xff1a; 首先&#xff0c;你需要创建一个元素&#xff0c;并获取其2D渲染上下文。 绘制斑马线&#xff1a; 使用fillRect或strokeRect方法绘制斑马线。你可以通过循环和计算来绘制多条具有不同宽度和间隔的…

1.PyQt6库和工具库QTDesigner安装

1.安装PyQT6和pyqt6-tools 1. PyQt6库是PyQt的开发库 2.pyqt6-tool时QTDesigner设计器工具支持库 pip install PyQt6 pip install pyqt6-tools 2.在Pycharm中配置外部工具QTDesigner和PYGIC 配置外部工具QTDesigner 1. QTDesigner是QT界面设计器 2.打开Pycharm->Settin…

【最新鸿蒙应开发】——HarmonyOS沙箱目录

鸿蒙应用沙箱目录 1. 应用沙箱概念 应用沙箱是一种以安全防护为目的的隔离机制&#xff0c;避免数据受到恶意路径穿越访问。在这种沙箱的保护机制下&#xff0c;应用可见的目录范围即为应用沙箱目录。 对于每个应用&#xff0c;系统会在内部存储空间映射出一个专属的应用沙箱…

Qt MaintenanceTool.exe使用镜像源更新Qt

环境&#xff1a;Windows11&#xff0c;Qt6.5&#xff0c;新版的MaintenanceTool.exe linux环境类似&#xff0c;mac环境可以看官方文档。 cmd命令窗口&#xff1a;切换到MaintenanceTool.exe所在目录&#xff0c;可以用“D:”切换到D盘&#xff0c;“cd xxxx”切换到xxxx目录…