开始啃 Erlang 程序设计,第二口

本章旨在介绍如何在Erlang环境中运行代码和编译模块,通过交互式ErlangShell进行学习,并展示如何利用Erlang编写高效并发程序。重点讲解了Erlang的进程、模块概念,以及如何创建并发进程。通过一个文件服务器实例,展示了Erlang在多进程编程上的优势,相比于C++/C#/Java更为简便。同时,介绍了客户端与服务器之间的通信模式,以及如何使用模式匹配简化代码逻辑。

Erlang 速览,既走马观花式的看看大概

本章要达到的学习目标:老Joe的要求是理解如何运行代码和编译模块,这两点,当然我得再掏出更多相关信息。并通过一个文件服务器的例子展示用Erlang 写多进程程序的优越性。反正确实比C++/C#/Java要方便很多。

                          1.如何运行代码

                          2.编译模块

2.1 Erlang Shell

        linux shell 下输入 erl 既进入 erlang shell  交互式会话中,它支持一种称为 REPL 方式来学习 erlang.

书上说请注意,每一条表达式,都必须以一个句号后接一个空白符结尾。我打了句号直接回车也行。

help(). 查看 erlang shell 中所有能输入的与 shell 相关的命令。

2.2 进程,模块和编译

模块是代码的容器,有两种形式,给人操作的源代码形式,给EVM操作的 抽象码形式。 源代码 --- erlc ---> 抽象码。

模块与进程的关系,就像类与对象的关系。一个是死的一个是活的。我觉得模块主要占内存,进程主要占CPU,两个占的系统资源不同。

进程负责执行模块里的函数。在 erlang shell里执行的情况与在 erlang shell外执行的情况不一样,看我写的第一篇,hello,erlang.

在 erlang shell外运行编译器,是编译erlang代码的首选方式, 因为可以利用 工程构建工具,使用项目自动化构建出来。书上说高级用户喜欢自动编译,对Erlang shell 的使用也会变少。那我得一开始从高手开始。

2.3 你好,并发

用于进程的代码包含在模块里,要创建一个进程, 需要调用spawn,创建进程。Erlang对代码采用一种所谓“尾递归”的优化,意思是此函数的运行空间是固定的。

------- file_server -------

receive 

{Client, list_dir} -> Client ! {erlang:self(), file:list_dir(Dir)};

{Client, {get_file, File}} -> Full = filename:join(Dir, File), Client ! {erlang:self(), file:read_dir(Full)}

end,

这段代码很紧凑,所以很容易忽略所发生的细节。(我反复读了10遍,确实没有多余的部分),抽象的很高的语言。

这段代码有三个要点:1.回复给谁 2. self()的用法 3.模式匹配被用于选择消息

Erlang编译器和运行时会正确推断出如何在收到消息时运行适当的代码。不需要编写任何的 if-then-else或 switch代码来设定该做什么, 这是模式匹配带来的乐趣之一,会为你节省大量工作。c(file_server).后 beam 载入EVM,就等待什么时候被其它进程调用,或自己 spawn 一个进程调用啦。同一个beam 可以 spawn N个进程出来,只要内存够大。

2.3.2 客户端代码

用一个 file_client模块来访问 file_server模块, 这个模块的主要目的是为了隐藏底层通信协议的细节。客户端代码可以通过调用此客户端模块导出的 ls, get_file 函数来传输文件。

------------ file_client.erl -----------------------------

-module(file_client).

-export([ls/1, get_file/1]). % 提供 2个 API供其它地方调用

% 一定要有这个 Server 参数,不然不知道要向哪个进程发消息,这个Server 就是 服务器的PID,向这个进程发消息,才有反应。

ls(Server) ->   %  一个用户接口

Server ! {erlang:self(), list_dir},   % 一定要先发个消息过反,服务器进程收到后匹配上了消息才能回过来,相当于一个激活过程。

receive 

{Server, FileList} -> FileList

end.

get_file(Server, File) -> % 第二个用户接口,第一步也是先要向 服务器进程发个消息,然后再处理接收的消息

Server ! {erlang:self(), {get_file, File}} ->

receive

{Server, Content} -> Content

end.

从Erlang角度看, 如何启动和停止服务器,连接套接字, 从错误中恢复等都是琐碎的细节(以后学到OTP框架自己都处理)。

而问题本质在创建并行进程 ,以及发送和接收消息。

在Erlang里用进程来构建问题的解决方案。思考进程的结构(也就是说哪些进程间相互有关联系),思考进程间传递的消息以及消息包含何种信息是思考和编程方式的中心。


   



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值