进程(Processes)

news2025/2/27 16:21:03

在 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.coloradmin.cn/o/1823511.html

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

相关文章

如何使用CCS9.3打开CCS3.0工程

如何使用CCS9.3打开CCS3.0工程 点菜单栏上的project,选择Import Legacy CCSv3.3 Porjects…,弹出对话框,通过Browse…按钮导入一个3.3版本的工程项目; 选择.pjt文件,选择Copy projects into worlkspace 右击选择P…

二分查找总结:算法原理,适用题型,经典题单

二分查找 感谢灵神的题单 题单:分享丨【题单】二分算法(二分答案/最小化最大值/最大化最小值/第K小) - 力扣(LeetCode) 每天四道题,大概用时一个月刷完,如果没有时间的同学可以学习我总结的算…

中信所:中国科学技术信息研究所-国家科技图书文献中心

文章目录 1. Intro2. History3. Staffing level4. Facility resources5. Scientific achievementsReference国家工程技术数字图书馆 National Engineering and Technology Digital Library 1. Intro 中国科学技术信息研究所(以下简称中信所)是在周恩来总理、聂荣臻元帅等党和…

【CS.AL】算法复杂度分析 —— 渐进符号表示法

文章目录 1 概述2 渐进符号详解2.1 大O符号(O)2.2 Ω符号(Ω)2.3 Θ符号(Θ)2.4 o符号(o)2.5 ω符号(ω) 3 具体例子3.1 插入排序(Insertion Sort…

GitHub强制双重验证、二次验证之下载微软Authenticator

Download Microsoft Authenticator 如上图,安卓手机在国内,基本没有下载使用的可能。 下载 Microsoft Authenticator 如上图,找到了国内下载渠道,但仅联想商店的新版本适合使用,下载安装即可。

C++11初始化列表打包器initializer_list

有时我们无法提前知道应该向函数传递几个实参。为了编写能处理不同数量实参的函数我们使用initializer_list Cplusplus中的定义: 其里面有三个成员函数 也就是说他是支持迭代器的,支持迭代器就支持范围for 图像理解 函数类型 void Test1_initializer_li…

一手洞悉巴西slot游戏包投放本土网盟CPI广告优势

一手洞悉巴西slot游戏包投放本土网盟CPI广告优势 在巴西这片热土上,slot游戏包的投放本土网盟CPI广告是一项既充满挑战又富有机遇的任务。CPI(Cost Per Install)广告模式,即按安装付费,已经成为许多游戏开发商推广产品…

ios18新功能:设专属“咒语”动动嘴巴即可操作iphone

苹果 iOS / iPadOS 18 系统引入了“人声快捷指令”(Vocal Shortcuts)功能,即便iPhone、iPad 处于锁屏状态下,也能响应你的语音命令。 苹果官方对“人声快捷指令”的介绍如下:iPhone 和 iPad 用户可以通过人声快捷指令…

2024牛客网高频精选Java面试八股文整理(附答案)

Java 面试 Java 作为编程语言中的 NO.1,选择入行做 IT 做编程开发的人,基本都把它作为首选语言,进大厂拿高薪也是大多数小伙伴们的梦想。以前 Java 岗位人才的空缺,而需求量又大,所以这种人才供不应求的现状,就是 Java 工程师的薪…

yolo模型评估指标相关概念

mAP(mean Average Precision 平均精度),是一个经常被用来衡量目标 检测模型是否具有较好性能的指标。 计算mAP需要先计算每一类物体的AP,然后取平均值,所以下面介绍的 TP,FP,FN,TN都是针对某一类物体(目标&…

CATIA软件 输入无参格式还原成为有参模型教程

上图为零件设计中特征辨识的命令栏,此次分享是对手动/自动特征辨识的命令应用,作个简单操作的分享了解。在CATIA软件中把输入的无参模型通过特征化后转化为有参模型的过程。其实CATIA软件早有这个功能提供给用户使用了,可能大家很少用。有了手…

数据通信与网络(二)

如何构建网络协议 这些协议采用分层的结构,每层协议实现特定功能,同时也需要依靠低层协议所提供的服务。 网络协议可以理解为三部分组成: 1、语法:通信时双方交换数据和控制信息的格式,是对通信时采用的数据结构形式…

【Numpy】numpy.r_用法

numpy.r_[字符串, 数组, 数组] numpy.r_的这三个整数默认值是0,1,-1 numpy.c_就是numpy.r_在三个整数是-1,2,0时的特例,因为常用,所以单独拎出来了。第一个参数-1指沿最后一个轴(维度)连接 有一个shape(2, 3, 4)的数组 np.random.randint(low0, high1…

Apache Tomcat介绍

目录 前言 一、Apache Tomcat的历史 二、核心特性与组件 三、Tomcat-基本使用 总结 前言 在Java Web开发领域,Apache Tomcat是一个不可或缺的核心组件。作为一个轻量级的开源Web应用服务器,Tomcat提供了一种简单而高效的方式来部署和管理Java Servle…

课外语文杂志课外语文杂志社课外语文编辑部2024年第4期目录

悦读时刻_我读经典 从忏悔到自救——鲁迅《风筝》的心灵叙事 杨丽; 5-7 读懂文字背后的深意——以《林黛玉进贾府》为例探索小说阅读之道 舒芳; 8-10 鲁迅笔下的真实与卑微——《故乡》中的人物形象 张淑堂; 11-13《课外语文》投稿:cn7kantougao163.com…

LLM基础知识

LLM背景知识介绍 1 大语言模型 (LLM) 背景 大语言模型 (英文:Large Language Model,缩写LLM) 是一种人工智能模型, 旨在理解和生成人类语言. 大语言模型可以处理多种自然语言任务,如文本分类、问答、翻译、对话等等。 💥通常&…

vivado HW_TARGET

HW_目标 描述 硬件目标hw_target是包含一个或多个JTAG链的系统板 Xilinx FPGA设备,您可以使用比特流文件进行编程,或用于调试您的设计。 系统板上的硬件目标与Vivado Design Suite之间的连接 由硬件服务器对象hw_server管理。 使用open_hw_target命令打开…

三款有3D效果的js图表库

1、G2简洁的渐进式可视化语法。https://g2.antv.antgroup.com/manual/extra-topics/3d-charts 2、 https://www.highcharts.com/https://www.highcharts.com/ 3、https://www.fusioncharts.com/charts/pie-doughnut-charts/donut-chart-in-3d?frameworkjavascripthttps://www…

聚鼎科技:现在的装饰画做起来难吗

在当代,装饰画作为一种体现个人品味和审美情趣的方式,已经广泛应用于各种室内空间。不少人会产生这样的疑问:在现代化技术和材料的支持下,制作一幅装饰画是变得容易了,还是依旧充满挑战? 现代科技的确为装饰画的制作带…

STM32项目分享:OV7670将图片上传电脑

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板及元器件图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片: 哔哩哔哩视频链接: https://www.bilibili.c…