📜  Erlang-并发(1)

📅  最后修改于: 2023-12-03 15:14:53.288000             🧑  作者: Mango

Erlang-并发

Erlang 是一种函数式编程语言,专注于构建分布式,高可靠性,高并发的软件系统。Erlang 可以轻松地为多个处理器和计算机构建分布式应用程序,并动态地将运行的进程分发到空闲的处理器。

并发编程的基础

在 Erlang 中,每个并发的单位称为进程。Erlang 进程轻量级,更容易管理,不需要太多的内存,而且非常快速地启动和停止。进程之间的通信使用消息传递模型,进程之间的通信是异步的。这意味着您无需关心进程何时会接收到消息,只需要发送它,由接收进程来处理。

创建进程

在 Erlang 中,有两种方式创建进程。第一种是使用 spawn/1 函数。该函数需要一个函数或模块名作为参数,用于启动新进程时要执行的操作。例如,以下代码创建一个新的进程并打印输出:

spawn(fun() -> io:format("Hello, world!~n") end).

第二种方式是使用 spawn/3 函数,该函数创建一个进程并传递数据作为参数。这些数据与要执行的操作一起传递给新进程。例如,以下代码创建一个新进程并输出它在主进程上的 PID:

spawn(fun(Pid) -> io:format("My PID is ~w.~n", [pid(Pid)]) end, [self()]).
发送和接收消息

在 Erlang 中,进程之间的通信只能通过传递消息实现。Erlang 提供了一个基本的消息传递系统,包括 Pid,用于标识进程,以及 !receive 运算符。

Pid 是 Erlang 进程标识符,是一个引用,用于发送和接收消息。可以使用 self() 函数获取当前进程的 Pid。例如,以下代码向进程 Pid 发送消息 “hello”:

Pid ! "hello".

receivecase 一样,是一种模式匹配语句。它允许您从发件人接收消息并对其进行处理。该过程等待消息的到来。在接收到消息之前,该进程将被停止。以下代码是对消息进行响应的模板:

receive
   Pattern1 [when Guard1] ->
      Expression1;
   Pattern2 [when Guard2] ->
      Expression2
end.

看一个示例:以下代码创建一个新进程,并向其发送一个 Atom 类型的消息 “start”。一旦接收到消息,该进程将在这里打印 “Hello, Erlang!”。

start(Pid) ->
   Pid ! start,
   receive
      start ->
         io:format("Hello, Erlang!~n")
   end.
并发编程示例

在 Erlang 中编写并发程序的良好例子是 WebSockets 服务器。回显服务器是一个经典的示例,它接收来自客户端的消息并将其发送回客户端。以下是一个简单的 WebSocket 服务器的示例:

-module(echo_server).
-export([start/1, stop/1]).

start(Port) ->
    {ok, Listen} = gen_tcp:listen(Port, [{active, false}, {reuseaddr, true}, binary]),
    io:format("Websocket server listening on port ~w~n", [Port]),
    loop(Listen).

stop(Listen) ->
    gen_tcp:close(Listen).

loop(Listen) ->
    {ok, Socket} = gen_tcp:accept(Listen),
    io:format("New connection!~n"),
    spawn(fun() -> handle(Socket) end),
    loop(Listen).

handle(Socket) ->
    gen_tcp:controlling_process(Socket, self()),
    receive
        {tcp, Socket, Data} ->
            io:format("Received: ~p~n", [Data]),
            gen_tcp:send(Socket, Data),
            handle(Socket);
        {tcp_closed, Socket} ->
            io:format("Socket closed!~n")
    end.

以上代码允许并发处理来自多个客户端的消息,并通过回显它们来响应。当客户端关闭 WebSocket 连接时会发生 tcp_closed 事件,此时进程会收到消息并停止。

结论

Erlang 以其独特的可伸缩、高并发并且容错的特性广受欢迎。与其他语言相比,Erlang 的并发编程方式可能需要一些适应,但它确实是一项非常强大的技术。Erlang 的并发编程是一个程序员的有力工具,可以帮助您为大型复杂的应用程序构建高度可伸缩的系统。