Erlang 中的并发性

Posted

技术标签:

【中文标题】Erlang 中的并发性【英文标题】:Conncurency in Erlang 【发布时间】:2021-05-27 17:20:16 【问题描述】:

我要解决的问题如下:

编写一个不带参数的名为 print_message 的 Erlang 函数。该函数应该等待接收消息。收到消息后(可以是任何 Erlang 术语),使用 io: format() 打印消息。如果 42 秒后未收到消息,则打印一条消息,显示“为时已晚”。

我为这个问题编写的代码如下:

    print_message() ->
      receive
       X -> io:format("~p~n",[X])
    after 42000 ->
       io:format("Too late ~n")
    end.

在我的问题中,它说“它可以是任何 Erlang 术语”。在我的代码中使用 X 是否满足该要求?或者我是否需要使用以下参考手册中所述的 any() 的 Erlang 内置函数: https://erlang.org/doc/reference_manual/typespec.html?

【问题讨论】:

【参考方案1】:

您的代码满足要求。

Erlang 是动态类型的。所以 X 的类型将仅在接收到第一条消息时确定,因此它可以是任何 Erlang 术语。

据我所知,我认为不可能在您的代码中指定 X 的类型。

在erlang中存在一些类型规范,但用于函数参数、返回值和记录定义。

这些类型定义可以在以后用于文档或dialyzer

【讨论】:

【参考方案2】:

是的,您的代码符合要求。模式 X 匹配任何 Erlang 术语。

与以下比较,仅当传入消息是一个以ok开头的2元组时才匹配:

print_message() ->
    receive
        ok, X ->

或者用这个,只有当传入的消息是一个整数时才匹配:

print_message() ->
    receive
        X when is_integer(X) ->

或者用这个,只有当传入的消息等于函数参数时才匹配:

print_message(X) ->
    receive
        X ->

(由于变量名称相同,这变成了选择性receive,所有其他消息都被忽略。)


类型规范是 Erlang 语言的可选部分。你可以指定你的函数接受一个整数并返回一个字符串:

-spec my_function(integer()) -> string().
my_function(N) ->
    ....

然后您可以使用 Dialyzer 检查类型错误。

但是,类型规范仅在编译时使用;他们实际上并没有在运行时执行任何检查。此外,它们不能用于指定发送或接收消息的类型;仅涵盖函数参数和返回值。

【讨论】:

以上是关于Erlang 中的并发性的主要内容,如果未能解决你的问题,请参考以下文章

并发编程中的原子性问题,可见性问题,有序性问题。

代码块和并发性

Azure SDK for .NET 中基于任务的 API 中的并发性

锁Redis锁 处理并发 原子性

并发编程系列之变量可见性问题探究

并发编程系列之变量可见性问题探究