【erlang】并发篇

news/2024/11/29 20:50:57/

PID类型

在之前的语法篇中,我们并没有介绍 PID这个类型,它和并发息息相关,因此我们在这里来学习它。

PID是进程标识符的意思,用来标识一个erlang进程。在所有相连的erlang节点中,PID都是唯一的。但是PID会被复用,当一个进程终止后,它的PID可以被其他进程再次使用。

进程ID用尖括号包裹的3个点分十进制表示 <x.y.z>,每个分量是一个十进制数字,一般 xz都是零,如果是一个远端主机上的进程的话,x就不为0了。

通过 self/0函数可以获取进程自己的PID,is_pid/1函数可以用来判断一个值是否是PID。

1> is_pid(1).
false
2> is_pid(<0.58.0>).
true
3> self().
<0.80.0>
4> is_pid(self()).
true

并发

erlang中并发的基本单元是函数,实现并发的函数是 spawn,它有两种调用方式:

  • spawn(Mod, Func, Args)
  • spawn(Fun)

spawn会在一个新的进程中执行指定的函数,注意这里所说的"进程"并不是操作系统的进程,而是erlang的进程,这种进程非常轻量,因此可以做到非常高的并发量。这两种方式的区别是第一种支持动态代码升级,后者不支持。

span函数的返回值就是进程PID,通过这个PID我们就可以给该进程发送消息了,这也是erlang中进程间通信的唯一方式。

发送消息

向一个进程发送消息的操作符是 !,语法为 Pid ! Message。该表达式的结果任然是 Message,这就意味着 Pid1 ! Pid2 ! ... ! Message也是合法的表示式,它会把 Message发送给 Pid1Pid2等所有进程。

消息是异步发送的,不会阻塞发送进程。

接收消息

接收消息的语法如下:

receivePattern1 [when Guard] ->Expressions1;Pattern2 [when Guard2] ->Expressions2;...
end

receive是阻塞式的,当消息到达时,会和每个模式进行匹配,并进行关卡验证,验证通过就会执行对应的表达式。receive只会接收一次消息,如果要循环接收,就需要使用递归。

超时

receive是阻塞式的,为了防止无限期等待,有时我们需要超时的功能。带超时的接收语法如下:

receivePattern1 [when Guard] ->Expressions1;Pattern2 [when Guard2] ->Expressions2;...
after Time ->Expressions
end

Time的单位是毫秒。超时时间有3种类型:

  • Time=0,立即超时。
  • Time=有限正数,正常超时。
  • Time=infinity,永不超时。

注意这里“等待”的含义并不是“等待消息的到来”,而是等待匹配的消息!这也就是说,即便是进程收到了消息,但是不能匹配接收语句的话,超时还是会执行。如果在超时之前,收到了与接收语句匹配的消息,那么超时语句就不会执行。

receive语句中可以只包含超时,它会让进程挂起一段时间,比如我们可以用它来实现一个sleep函数。

sleep(T) ->receiveafter T ->trueend.

另一点需要注意的是,即便是时间为0的超时,在执行超时语句之前,进程也会先将自己邮箱中的消息与接收语句匹配一遍,如果能够匹配,那么超时也不会执行。我们可以用一个例子来说明这一点。

-module(chaoshi).-export([test_recv/0]).test_recv() ->receiveyes -> io:format("yyds~n")after 0 -> test_recv2()end.

在erlang shell中编译上面的代码,然后执行下面的命令:

2> Pid = spawn(chaoshi, test_recv, []).
<0.116.0>
3> Pid ! yes.
yyds
yes

如果不是先对邮箱中的消息进行匹配,那么yyds是永远不可能被打印的。

receive的流程

receive除了做消息匹配还会做消息管理和超时管理,一个典型的接收语句如下:

receivePattern1 [when Gruad1] ->Expression1;Pattern2 [when Gruad1] ->Expression2;...
afterTime ->ExpressionTimeout
end.

它的工作流程如下:

  1. 启动一个定时器(如果有after的话)。

  2. 取出进程邮箱的第一条消息,与各个模式匹配,如果匹配成功,将消息从邮箱移除,并执行模式后的表达式。

  3. 如果第一个消息不能和任何一个模式匹配,系统会将它从进程邮箱移出,放入一个队列保存起来,然后继续尝试第二条消息,重复这一过程直到找到匹配的消息或者邮箱为空。

  4. 如果所有消息都不匹配,则进程被挂起并重新调度,直到有新消息时到达时,才继续匹配新消息,队列里的消息不会重新匹配。

  5. 如果新消息匹配成功,队列里的消息会按原顺序重新放入邮箱,如果启动了定时器,会取消定时器。

  6. 如果定时器先到期了,就会执行ExpressionTimeout,并将队列里的消息按原顺序重新放回邮箱。

注册进程

向进程发送消息就需要知道进程的PID,而要记住一个进程的PID是比较难的,而且每次启动进程PID都会变化。

注册进程就是将一个PID和一个原子关联起来,并通过某种方式公布出去,相当于给进程取个名字,这样其他进程通过这个名字就可以给这个进程发送消息了。DNS域名解析以及微服务的服务注册都是相同的套路。

与进程注册有关的函数有4个:

  • register(Name, Pid)
    Name(原子类型)与 Pid关联,如果 Name已被注册,此次注册会失败。一旦注册成功,就可以通过 Name ! Message向进程发送消息。
  • unregister(Name)
    取消注册,移出与 Name关联的所有注册信息。如果注册进程崩溃,会自动取消注册(这真是太棒了)。
  • whereis(Name)->Pid | undefined
    检查 Name是否已被注册,如果是就返回进程PID,否则返回 undefined
  • registered()->[Name::atom()]
    返回系统里所有注册进程的名称列表。


http://www.ppmy.cn/news/47608.html

相关文章

CSS基础——CSS基础(下)

目录 继承 选择器的优先级 优先级规则 a的伪类优先级 文本标签及样式 文本标签 em、strong、i、b small cite q blockquote sup、sub ins、del code、pre 文本样式 text-transform text-decoration letter-spacing word-spacing text-align text-indent 长…

正则表达式的字符串取反常用正则表达式

正则表达式的字符串取反操作 文件同步时&#xff0c;想要过滤掉扩展名为.tmp或者.TMP的临时文件&#xff0c;想要使用正则表达式对字符串进行取反操作。 注意&#xff1a;[^tmp]* 这种取反的表达式&#xff0c;只能表示匹配除了t、m、p以外的所有字符&#xff0c;是单字符匹配…

LeetCode 1042. 不邻接植花

【LetMeFly】1042.不邻接植花 力扣题目链接&#xff1a;https://leetcode.cn/problems/flower-planting-with-no-adjacent/ 有 n 个花园&#xff0c;按从 1 到 n 标记。另有数组 paths &#xff0c;其中 paths[i] [xi, yi] 描述了花园 xi 到花园 yi 的双向路径。在每个花园中…

Hystrix详解

前言 Hystrix基于Feign&#xff0c;想熟悉Hystrix&#xff0c;必须先熟悉Feign。 Feign&#xff08;简介和使用&#xff09;&#xff1a; Feign&#xff08;简介和使用&#xff09;_长头发的程序猿的博客-CSDN博客 Hystrix简介 hystrix对应的中文名字是“豪猪”&#xff0c…

关于小程序云开发cms内容管理无法使用,无法同步内容模型到云开发数据库的解决方案

小程序官方最近又搞大动作了&#xff0c;偷偷的升级的云开发cms&#xff08;内容管理&#xff09;以下都称cms&#xff0c;不升级不要紧&#xff0c;这一升级&#xff0c;就导致我们没有办法正常使用cms了。如果你开通完cms带下面这个标识的话&#xff0c;就代表你是新版本&…

ChatGPT对于程序员到底是机遇还是挑战?深度体验告诉你

目录 一、人工智能的快速发展 二、机遇 1.自动化生产 2.新技术的探索 3.更高的薪酬 三、挑战 1.竞争压力 2.人类工作替代 程序员应该如何应对 ChatGPT 的机遇和挑战 1. 学习新技术 2. 注重团队合作 3. 加强人际交往 4. 保持开放心态 5. 保护个人隐私 结论 &#x1f416;&#x…

离线前期准备

目录 项目的需求分为一下几点&#xff1a; 技术选型&#xff1a; 主要需求技术&#xff1a; 项目的需求分为一下几点&#xff1a; 用户行为数据采集的平台搭建业务数据采集的平台搭建数据仓库的维度建模分析、设备、会员、商品、地区、活动等电商核心主题、统计的报表指标近10…

PageRank算法介绍

互联网上有数百亿个网页&#xff0c;可以分为这么几类&#xff1a;不含有用信息的&#xff0c;比如垃圾邮件&#xff1b;少数人比较感兴趣的&#xff0c;但范围不是很广的&#xff0c;比如个人博客、婚礼公告或家庭像册&#xff1b;很多人感兴趣的并且十分有用的&#xff0c;比…