关键词不能为空

当前您在: 主页 > 英语 >

erlang基础知识集锦

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2020-10-25 04:46
tags:hrl

宽泛-命运多舛什么意思

2020年10月25日发(作者:支大纶)


Erlang基础知识集锦
声明:此文档只作为对erlang的认知之用,如果需要 学习并使用erlang
请系统学习介绍erlang的书。
1. 简介
? Er lang是一个并行编程语言和运行时系统,最初由爱立信(Ericsson)于1987年
为电信行 业所开发。1998年爱立信在改良的MPL(Mozilla Public License)许可
下将Erlang发布于开源社区。
? Erlang是:
a) 一种“小众”语言。
b) 一种函数式语言 (变量只能赋值一次)。
c) 一种动态类型语言(变量类型在运行时决定,代码需要编译后才能执行,与
Python,Ruby等不 一样)。
d) 一种强类型语言。
e) 一种面向并发(Concurrency Oriented)的语言。
2. 特性
?
?
?
?
?
?
?
并发性 - Erlang支持超大量级的并发线程,并且不需要操作系统具有并发机制。
分布式 - 一个分布式Erlang系统是多个Erlang节点组成的网络(通常每个处理
器被作为一个节点)。
健壮性 - Erlang具有多种基本的错误检测能力,它们能够用于构建容错系统。
软实时性- Erlang支持可编程的“软”实时系统,使用了递增式垃圾收集技术。
热代码升级-Erlang允许程序代码在运行系统中被修改。旧代码能被逐步淘汰而后
被新代 码替换。在此过渡期间,新旧代码是共存的。
递增式代码装载-用户能够控制代码如何被装载的细节。
外部接口- Erlang进程与外部世界之间的通讯使用和在Erlang进程之间相同的消
息传送机制。
3. 数据类型
3.1. 变量
3.1.1. 在erlang中的变量只能被赋值一次,变量第一个字母要是大写的。
3.1.2. 符号”=”是值类型匹配操作(带有赋值的意思)。(pattern matching)
3.1.3. 在erlang中变量是不可变的,也没有共享内存的概念,也没有锁。
3.2. 浮点数
3.2.1. 整数除法示例: 4 div 2。
3.2.2. 求余示例: 5 rem 2。
3.2.3. “”永远返回浮点数。
3.3. Atoms(原子)
3.3.1. Atoms表示不同的非数字常量值。
3.3.2. 示例: Xss = 'Asss'。


3.4. 元组
3.4.1. 将若干个以逗号分隔的值用一对大括号括起来就形成了一个元组。
3.4.2. 元组示例: Person = {person, {name, joe}, {height, 1.83}, {footsize, 42}}.
3.4.3. 从元组中提取数据:
Point = {point, 10, 45}.
{point, X, Y} = Point.( pattern match)
此后X=10, Y=45.

3.5. 列表

3.5.1. 将若干个以逗号分隔的值用一对方括号括起来,就形成了一个列表。
3.5.2. 示例: ThingsToBuy = [{apple, 10}, {pear, 6}, {milk, 3}].
3.5.3. 列表中的第一个元素叫做列表头,剩下的部分叫做列 表尾。一般来说列表头
可以是任何东西,列表尾经常是一个列表。
3.5.4. 访问列表头元素是一个非常高效的操作。
3.5.5. 从列表中解析元素:
ThingsToBuy1 = [{oranges, 4}, {newspaper, 1}|ThingsToBuy].
[Buy1|ThingsToBuy2] = ThingsToBuy1.
此后:ThingsToBuy1 = [{oranges,4},{ newspaper,1},{apple,10},{pear,6},{milk,3}].
Buy1 = {oranges,4}.
ThingsToBuy2 = [{newspaper,1},{apple,10},{pear,6},{milk,3}].

3.6. 字符串
3.6.1. 在erlang中没有字符串,字符串仅仅是整数列表。用双引号将一串字符括
起来就是一个字符串。
3.6.2. 示例:
Name =
5>I = $$s.
115
8> [I-32, $$u, $$r, $$p, $$r, $$i, $$s, $$e].

4. Erlang基本语法

4.1. 模块
4.1.1. Erlang源文件是以.erl做为扩展名的,头文件是以.hrl做为扩展名的。
4.1.2. 要运行一个模块,首先要编译它,编译以后的文件是以.beam做为扩展名的。
文件编译命令:c(M odulename).
4.1.3. 改变erlang的工作目录
在操作系统用户文件 夹下找到目前登录用户的文件夹在其中建立一
个.erlang文件夹,在这个文件中写上:c:cd( "you work dir"). 重启
erlang shell就改变了工作路径。
4.1.4. 在erlang中符号的使用:
逗号(,)用来分隔函数调用,数据构造器(列表元组中的逗号)以及模式中的
参数。
句号(.)(后面跟一个空白符号)用来在shell中分隔完整的函数和表达式。

< br>分号(;)用来分隔子句,在以下几种情况下都会用到子句:分段的函数定
义,case子句, if语句, try?catch语句, 以及receive表达式。
4.1.5. 调用模块中的方法:Modules:ExportFunc(?)

4.2. 匿名函数(fun关键字)
4.2.1. 使用示例:
1> Hypot = fun(X, Y) -> math:sqrt(X*X + Y*Y) end.
#Fun
2> Hypot(3, 4).
5.0

4.2.2. 匿名函数可以作为函数的参数,并且作为函数的返回值。
4.2.3. 定义自己的抽象控制流程:
for(Max, Max, F) -> [F(Max)];
for(I, Max, F) -> [F(I)|for(I+1, Max, F)].

4.3. 简单列表处理
4.3.1. map函数示例
:
map(_, []) -> [];
map(F, [H|T]) ->[F(H)|map(F, T)].
1> L = [1,2,3,4,5].
[1,2,3,4,5]
map(fun(X) -> 2*X end, L).
输出:[2,4,6,8].
4.4. 列表理解
4.4.1. 示例:

1> L = [1,2,3,4].
[1,2,3,4]
2> [2*X || X <- L].
[2,4,6,8]

1> Buy = [{oranges, 4}, {newspaper, 1}, {apples, 10}, {pears, 6}, {milk,
3}].
[{oranges,4},{news paper,1},{apples,10},{pears,6},{milk,3}]
2> [{Name, 2*Number} || {Name, Number} <- Buy].
[ {oranges,8},{newspaper,2},{apples,20},{pears,12},{ milk,6}]


4.5. 算数表达式(以及优先级)

参见下图:




4.6. Guard
4.6.1. Guard是一种强化模式匹配功能的结构,使用Guard可以在一个模式上做一些简单的变量测试和比较。
4.6.2. 示例
:
max(X, Y) -> when X > Y -> X;
max(X, Y) -> Y.
4.6.3. Guard组合关系
?
?
Guard1;Guard2...;Guardn 条件式中每个条件式是or关系。
Guard1,Guard2...,Guardn 条件式中每个条件式是and关系。
4.6.4. 合法的Guard表达式:
? 原子true。
? 其它常量(字典或者列表中的条目或者绑定变量), 这些在断言表达式
?
?
?
?
?








中都会被求值为false。
表下表一中的这些内建函数。
比较表达式,参见表二。
算数表达式。参见表三。
布尔表达式。
短路布尔表达式


表一:

表二:

表三:




4.6.5. Guard例子
f(X, Y) when is_integer(X), X > Y, Y < 6 ->...
4.6.6. true Guard的使用:
true Guard可以在if表达式的末尾处理所有为被匹配的Guard。
if
Guard -> Expression1;
Guard2 -> Expression2;
?
True -> Expressions
end

4.7. 记录(Records)

4.7.1. 使用场景
当元组的元素数量比较大的时候我们可能不知道某个【元素】的具体意义,
这个时候 就可以使用记录。
4.7.2. 申明示例:
-record(todo, {status=reminder,who=joe,text}).
4.7.3. 在shell中读取recode的方法:
rr(SomeErlangHeadFile).
4.7.4. 使用示例:
1>#todo{}.
#todo{status = reminder, who=joe, text = undefined}
3>X1 = #todo{status = urgent, text =
#todo{status = urgent, who = joe, text =
4>X2 = X1#todo{status = Done}
#todo{status = done, who = joe, text =

5>#todo{who = W, text, Txt} = X2.
#todo{status = done, who = joe, text =
6>W.
joe
7>X2#.

4.7.5. 在函数中对记录进行模式匹配:
clear_status(#todo{status=S, who=W}) ->
R#todo{status=finished}
4.7.6. 记录只是元组的伪装


11>X2.
#todo{status = done, who = joe, text =
12>rf(todo).
Ok
13>X2.
{todo, done, joe,
4.8.
case和if表达式
4.8.1. case语句的语法
case Expression of
Pattern1 [when Guard1] -> Expr_seq1;、
Pattern2 [when Guard2] -> Expr_seq1;
...
End
4.8.2. case语句示例:
filter(P, [H|T]) ->
case P(H) of
true -> [H|filter(P, T)];
false -> filter(P, T)
end;
filter(P, []) ->
[].

4.8.3. if语句的语法
if
Guard1 ->
Expr_seq1;
Guard ->
Expr_seq1;
...
End
5. erlang中的异常

5.1. erlang异常的产生

异常经常在系统内部错误或在代码中显式调用throw(Exception),
exit(Exception), erlang:error(Exception).
5.2. 自己生成异常的方法
? exit(Why)
当想要终止当前进程的时 候,就需要用到这个函数,如果这个异常未被捕获,
那么系统会向所有与当前进程相连接的进程广播{“ EXIT”, Pid, Why}消息。
? 这个函数用于抛出一个调用者可能会捕获的异常,在这 种情况下,有必要为函
数添加注释说明它会抛出这个异常。这个函数的调用者有两种选择,要么忽略这些异常,要么将这个调用包含在try?catch表达式中并对错误进行处理。
erlang:error(Why)
这个函数用于抛出那些”崩溃错误”。这些异常应该是那些调用者不会真正意
?


识到去处理的致命错误,可以将它等同于内部产生的系统错误。
5.3. try?catch
5.3.1. 语法形式:
try FuncOrExpressionSequence of
Pattern1 [when Guard1] -> Expressions1;
Pattern2 [when Guard2] -> Expressions2;
...
catch
ExceptionType: ExPattern1 [when ExGuard1] ->ExExpressions1;
ExceptionType: ExPattern2 [when ExGuard2] ->ExExpressions2;
...
after %%after部分可以省略
AfterExpressions %%这个地方的返回值将会被忽略
end
在以上语法中ExceptionType是throw, exit, error中的一种假如
ExceptionType被忽略则它的默认类型为throw.

5.3.2.
捕获所有的错误
try Expr
catch
_:_ -> ...Code to handle all exceptions.
End
5.3.3.
使用示例:

try_

(ej@)1> c(try_test).
{ok,try_test}
(ej@)2> try_test:demo1().
[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]
(ej@)3> try_test:demo2().
[{1,a},
{2,a},
{3,{'EXIT',a}},
{4,{'EXIT',a}},
{5,
{'EXIT',{a,[{try_test,generate_exception,1},
{try_test,'-demo20-lc$$^01-0-',1},
{try_test,'-demo20-lc$$^01-0-',1},
{erl_eval,do_apply,5},


{shell,exprs,7},
{shell,eval_exprs,7},
{shell,eval_loop,3}]}}}](ej@)


6. Erlang高级语法

6.1. 二进制数据操作:

示例一:
1> Bin1 = <<1,2,3>>.
<<1,2,3>>
2> Bin2 = <<4,5>>.
<<4,5>>
3> Bin3 = <<6>>.
<<6>>
4> list_to_binary([Bin1, 1, [2,3,Bin2],4|Bin3]).
<<1,2,3,1,2,3,4,5,4,6>>

示例二:
1> Red = 2.
2
2> Green = 61.
61
3> Blue = 20.
20
4> Mem = <>.
<<23,180>>
5> <> = Mem.
<<23,180>>
6> R.
2
6.2. apply关键字

6.2.1. 格式
apply(Mod, Func, [Agr1, arg2,...,ArgN])
此方法调用模块Mod中的参数为[Agr1, arg2,...,ArgN]的Func方法。
6.2.2. 建议
如果可能的话应避免用此种方法调用其它模块中的方法,当一个函数的参 数
个数提前知道,更好的调用方式是:M:F(Arg1, Arg2,....ArgN).
6.2.3. 使用示例:
1> apply(erlang, atom_to_list, [hello]).

2> erlang:atom_to_list(hello).

6.3. (模块)属性
6.3.1. 常见模块属性


-module(modname).
-import(...).
-export(...).
-compile(Options).
-vsn(Version).
最后一个选项为增加编译选项,Options可以是单个选项或者选项列表。
-compile(export_all)属性经常被使用在调试程序中。
-vsn(Version).中的Version可以是任意字符条目。
6.3.2. 自定义属性
格式:
-SomeTag(Value).
(例如:-purpose(
6.3.3. 常看模块属性
Module:module_info().
Module:module_info(exports).
6.4. 块表达式(Block Expressions)

6.4.1. 语法形式
begin
Expr1,
...
ExprN
end
块表达式用来把一串表达式组织成一个类似子句的实体,块表达式的值为最后
一个表达式的返回值。
6.5. 布尔类型
Erlang中没有独立的布尔类型,原子true和false取而代 之被赋予了特殊的布尔
语义,它们通常作为布尔符号使用。
6.6. 布尔表达式
6.6.1. 4种布尔表达式:
not B1: 逻辑非
B1 and B2: 逻辑与
B1 or B2: 逻辑或
B1 xor B2: 逻辑异或
6.6.2. 使用举例
1>not true.
false
2>true and false.
false
3>true or false.
true

6.7. 转义符
6.7.1. 转义列表



6.7.2. 使用举例

1> io:format(
[8,127,27,12,10,13,32,9,11,32]
6.7.3. 表达式和表达式序列
在erlang中,任何可以被求出值的东西都被称作表达式。这意味着catch,
if, try?catch等都是表达式,而类似记录和模块属性等,这些不能被求值
的都不是表达式。
表达式序列是一系列由逗号分开的表达式。这些表达式都应该紧接放置
于->之后,表达式序 列E1,E2,?,En的值被定义为序列中最后一个表达式的
值。
6.8. 包含文件
-include(Filename)
Filename应该包好一个绝对或相对路径以便预处理器能够定位到相应的文件。
-include_lib(Filename)
这是包含了erlang库中的头文件。
6.9. 列表操作符++和—
1> [1,2,3]++[4,5].
[1,2,3,4,5]
2> [a,b,c,1,d,e,1,x,y,1]--[1].
[a,b,c,d,e,1,x,y,1]
4> [a,b,c,1,d,e,1,x,y,1]--[1,1].
[a,b,c,d,e,x,y,1]
6.10. 宏
6.10.1. 语法
-define(Constant, Replacement).
-define(Func(Var1, Var2,...,Var), Replacement).
使用


-define(macro1(X, Y), {a, X, Y}).
?
foo(A)
?macro1(A+10, b)
6.10.2. 预定义宏
?FILE 展开后为目前文件名
?MODULE 展开后为目前模块名
?LINE 展开后为目前行号
6.10.3. 宏的流程控制
-undef(Macro) .取消改宏定义,在这个语句之后不能调用这个宏。
-ifdef(Macro).只有Macro被定义后,才对该行以下的代码进行运算。
- ifndef(Macro).只有在不定义Macro的情况下,才对该行以下的代码进行
运算。
-else. 只能在-ifdef或-ifndef之后出现,如果条件为false, 那么改语句
后的代码才被执行。
-endif.标记-ifdef或- ifndef语句的结束。
6.10.4. 使用举例
-undefine(Macro).
-ifdef(Macro).
-ifndef(Macro).
-else.
-endif.


-module(m1). %%module name is m1
-export([start0]).

-ifdef(debug).
-define(TRACE(X), io:format(~p:~p ~p~n?LINE,
X])).
-else.
-define(TRACE(X), void).
-endif.

start() -> loop(5).

loop(0) ->
void;
loop(N) ->
?TRACE(N),
loop(N-1).

编译以上脚本的方法:c(m1,{d, debug}).
运行方法:m1:start().



6.11. 在模式中使用匹配操作符

在函数参数中将传进来的参数在参数列表中尽量赋给一个临时变量, 这样在接下
来的操作中会比较方便,如:
func1([{tag1, A, B}=Z|T])

6.12. 数值类型
6.12.1. 整数
? 传统语法 直接书写10, 50, -7。
? K进制整数 语法K#Digits来表示
1> 7#456114.
81351
? $$语法 语法$$C表示ASCII字符C的整数值。
6.12.2. 浮点数
1.0 3.14 -2.3E+6 23.56e-27
浮点数的范围:-10^323~10^308
6.13.
操作符优先级

6.14. 进程字典

E rlang的每个进程都有自己的私有数据存储,叫做进程字典。进程字典是由一系
列组成的关联数组, 进程字典的操作方法如下:
? @spec put(Key, Value) -> OldValue
增加一个键值到进程字典,如果进程字典中原来就有这个键,那么这个
值将 会被返回,如果进程字典中原来没有这个键,那么将会返回atom
类型的undefined。
?
?
?
?
?
@spec get(Key) ->Value
@spec get() -> [{Key, Value}...]
@spec get_keys(Value) ->[Key].
@spec erase(Key) ->Value.
@spec erase() ->[{Key, Value}]. --擦除进程字典中的所有键值
6.15. 引用
引用是全局唯一的erlang值,使用BIF erlang:make_ref()来创建引用,引 用适
用于创建那些唯一标签的场合,例如:在一个BUG跟踪系统中,可以给每一个新的


bug报告加入一个引用,以便改记录赋予一个唯一标识。
6.16. 短路布尔表达式
Expr1 orelse Expr2
首先求值的是表达式Expr1。如果Expr1为 true,那么Expr2就不会被求值,如果
Expr1运算结果为false,才会对Expr2进 行求值。
6.17. 比较表达式
6.17.1. 为了进行比较,erlang按照下面的方式为所有类型定义了大小比较顺序

number < atom < reference < fun < port < pid < tuple < list < binary.

6.17.2. 比较表达式

除了=:=和==, 所有的条目比较运算符在比较数字的时候有如下规则:
? 在比较的过程中如果有一个数字为整数另一个为浮点数则在比较
前整数会转变为浮点数。
? 如果都是整数或者浮点数则没有数据转换。
示例:
1>15 =:= 15.0 数据类型不转的情况
False
2>15 == 15.0 数据类型转的情况
True
6.18. Underscore Variables(强调变量,下划线变量)
正常情况下,假如一个变量在一个子句(clause )中仅被使用了一次,编译器将会生
成一个警告, 因为这经常被认为是一种错误的标志,如果在一个变量前加一个下划
线将不会生成这样一个警告。

7. 编译和运行erlang程序
7.1. 和运行环境相关的API
以下函数设置erlang程序运行时模块的搜索路径:
@spec code:get_path()
@spec code:add_patha(Dir) => true|{error, bad_directory} %%在模块搜索目
录头上增加搜索目录
@spec code:add_pathz(Dir) => true|{error, bad_directory} %%在模块搜索目
录尾上增加搜索目录


@spec code:all_loaded()
获取erlang程序运行的起始目录:
init:get_argument(home).

8. 并行编程
8.1. Erlang中进程特点
?
?
?
?
创建和摧毁进程的速度很快。(2-4ms(微妙),win7 32 bit 操作系统,双核CPU,
3.37G内存)
进程的行为在所有的操作系统中表现的一样。
我们可以有大量的进程。
进程之间没有内存共享,它们是完全独立的。
? 进程之间交互的唯一方式是消息传递。
8.2.
Erlang进程的理解:


(ej@)1> c(processes).
{ok,processes}
(ej@)2> processes:max(20000).
Maximum allowed processes:32768
Process spawn time=3.1 (3.15) microseconds
ok
修改默认最大进程数的方法:
erl +P 100000 将系统的最大线程数设置为10万。
8.3.
并发原语
?
?
Pid = spawn(Fun)
建立一个新进程 此进程和调用进程并行工作。
Pid|Message (Pid1 | Pid2 |...|M)
代表发送操作,消息发送是异步的。(在实际代码中|是!)
8.4. 设置接收超时值

8.4.1. 语法:
receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard2] ->
Expressions2;
...
after Time -> %%Time为milliseconds毫秒
Expressions
end
after部分只有在消息队列中的所有消息被遍历过之后才会被执行.
after section is checked only after pattern matching has been
performed on all entries in mailbox.


8.4.2. receive的工作方式
?
?
当进入一个receive语句时,启动一个计时器(只有在表达式有after部分才< br>计时)。
从mailbox(邮箱)中取出第一个消息,然后尝试对Pattern1,Pat tern2等
进行模式匹配。如果匹配成功,消息就从邮箱中删除,对应的模式之后的表达
式就 会被求值。
如果邮箱中的第一个消息不能匹配receive语句的任何一个模式,那么就会将
第一个消息从邮箱中删除并送入一个“保存队列中”,然后继续尝试邮箱中的
第二个消息。这个过程会 不断的重复直到找到匹配的消息或者邮箱中所有的消
息全部被检查了。
? 如果邮箱中所有的 消息都不能匹配,那么就挂起进程,直到下一次又有新的消
息进入邮箱时在对该进程进行重新调度执行。 注意,当一个新消息到达时,只
?
对新消息进行匹配而不会对保存队列中的消息进行再次匹配
一个消息如果被匹配,那么存入保存队列中的所有消息就会按照它们到达进程
的时间先后顺序重 新放回到邮箱中,这时,如果开启了一个计时器,那么计时
器将会被清空。
? 如果在我们等 待一个消息时触发了计时器,那么先对超时部分中的语句进行求
值然后把存入保存队列中的所有消息按照 它们达到进程的时间先后顺序重新
放回到邮箱中。
?
8.4.3. 超时使用示例:


1> c(stimer).
ok
2> Pid = stimer:start(5000, fun() -> io:format(event~n
end).
<0.146.0>
time event
3> Pid1 = stimer:start(25000, fun() -> io:format(
end).
<0.143.0>
4> stimer:cancel(Pid1).
cancel

8.5. 注册进程

erlang进程能够发布一个进程的ID以至于任何在系统中的进程可以和他交互 。有
以下4个方法可以操作注册进程:
? spec register(AnAtom, Pid)
注册一个名字叫做AnAtom,ID是Pid的进程,假如AnAtom已经被注册过了,
那么这个注册操作将会失败。
? spec unregister(AnAtom)
移除一个与AnAtom有关的注册。
假如一个进程死掉,它将会自动的取消注册。


?
?
spec whereis(AnAtom) -> Pid | Undefined
registered() -> [AnAtom::atom()]
返回在系统中注册的所有的进程的列表。
8.6. 从另一个模块中启动进程的方法

spawn(Mod, FuncName, args)

9. 并行编程中的错误处理
9.1. 错误处理的细节

9.1.1. 错误处理中的3种基础概念
? 连接(Links): 一个连接定义了一个错误传播路径,假如两个 进程连接到一
起然后其中的一个死掉,接下来一个退出信号将会被发送到另一个进程,
?
连接到一个进程的其它进程被叫做这个进程的进程集合。
退出信号(Exit Signal s):一个进程死掉的消息会发送给这个进程的进程
集合。进程可以调用exit(Reason)或者 程序内部发生错误将会发送进程退
出的消息。除此之外Pid1还可以调用exit(Pid2, X)发送{Pid, X}
?
消息给Pid2, 但是Pid1不会死掉。
系统进程(system processes): 可以将其它进程的退出消息转化为普通的
消息的进程叫做系统进程。一般进程可以调用内建函数
process_flag(trap_exit , true)来将自己转化为系统进程。
9.2. 错误处理原语(Error Handing Primitive)
? @spec spawn_link(Fun) ->Pid
s pawn_link是原子操作,其不等于spawn之后调用link,因为调用spawn之
后的进 程可能死掉。
@spec process_flag(trap_exit, true)
将目前的进程转化为系统进程。
也可以用process_flag(trap_exit, false) 将系统进程转化为一般进程。
?
?
?
?
?
@spec link(Pid) ->true
假如连接一个不存在的进程,则noproc异常抛出。
@spec unlink(Pid) ->true
解连接。
@spec exit(Why) -> none()
这条原语引起目前进程因为Why原因结束。
@spec exit(Pid, Why) -> true
此条原语发送原因为Why的退出信号。
@spec erlang:monitor(process, item) -> MonitorRef
此条原语安装了一个监督者,item是PID或者一个进程的注册名。
?
10.分布式编程

10.1.
10.2.
名字服务服务器
分布式原语
参见中文<> p145。
erlang分布式的中心概念是节点,一个节点。相互交流的节点之间cookie要相同。
erlang:set_cookie() 可设置节点的cookie值。


? @spec spawn(Node, Fun) ->Pid
约等于spawn(Fun)
在一个节点上产生一个进程
@spec spawn(Node, Mod, Func, ArgList) -> Pid
约等于spawn(Mod, Func, Arglist)。
这个方法是原子操作执行过程中不能被打断。
@spec spawn_link(Node, Fun) ->Pid
类似:spawn_link(Fun)。
@spec spawn_link(Node, Mod, Func, ArgList) -> Pid
类似于:spawn(Node, Mod, Func, ArgList)。
新创建的进程链接到目前的进程。
?
?
?
?
?
@spec disconnect_node(Node) -> bool |ignored
强制中断一个节点。
@spec monitor_node(Node, Flag) -> true
假如Flag=true,监视被打开,Flag = false, 监视被关闭。
当flag = true时调用此内建函数的进程将会收到{nodeup, Node},
?
?
?
?

当某个节点不在此进程的监视集合中的时候{nodedown, Node}将会被收到。
@spec node() -> Node
此方法返回本地节点的名字,
@spec node(Arg) -> Node
此函数返回Arg所在的节点,Arg可以是PID, 一个名字引用,或者一个port。
@spec nodes() -> [Node]
返回一个连接上的所有节点的列表。
@spec is_alive() ->bool()
11.接口技术
接口技术 就是让erlang与其他语言结合,erlang与其它语言结合的方式也
是发送消息机制。

_server

12.1. 简介
gen_serv er实现了一个client_server模式,在这个模式中的client
可以有任意个。这种模 式通常被使用在不同的客户端想要共享共同的资
源,此中情况下服务端负责管理这些共享的资源。
12.2. 代码
my_
12.3.

使用方法
(ej@)1>
c(my_bank).

{ok,my_bank}
(ej@)2>
my_bank:start().


{ok,<0.79.0>}
(ej@)3>
my_bank:new_account(

{welcome,
(ej@)4>
my_bank:deposit(

{thanks,
(ej@)5>
my_bank:deposit(

{thanks,
(ej@)6>
my_bank:withdraw(

{thanks,
(ej@)7>
my_bank:withdraw(

{thanks,
(ej@)8>
my_bank:stop().
stopped

12.4. my_文件代码分析
12.4.1. –behaviour(gen_server).(11行)此句的作用是当我们忘 记需要实现的
回调函数的时候编译器会产生警告或者错误消息。
12.4.2. start ().(19行)此句为启动一个本地(回调)服务,将第一个列表参数中
的local换为globa l参数,将启动一个能在由erlang节点组成的集群中全
局访问的(回调)服务。此函数经过gen _server中的事件分发最终会调用
my_模块中的init([])(28行)函数。
12.4.3. stop().(20行)此句为停止本地回调服务。此函数经过gen_serve r中的
事件分发最终会调用my_模块中的handle_call(stop, _From,
Tab)(57行)函数。
12.4.4. new_account(?), deposit(?), withdraw(?)为在开户,存款,取款功
能。此函数最终会调用my _模块中的handle_call(?)函数。
12.4.5. handle_cast(?)( 60行)是gen_server:cast(?)的回调。cast函数是一
种没有返回值的调用。( 返回的时候的atom:noreply).
12.4.6. Handle_info(?)用来处 理发送给服务器的原生消息。原生消息就是:如果
服务器和其他的进程建立了连接,并且正在捕捉退出事 件,那么它有可能会
突然收到意外的{‘EXIT’, Pid, What}这样的消息。又或者,系 统中的其
它进程获得了服务器程序的PID,那么它可能会给服务器发送消息。
12.4.7. terminate(?).服务器终止的时候调用的回调函数。
12.4.8. code_change(?).在热代码升级的时候被回调。

_event
13.1. 简介
一个事件处理器就是一个命名对象(一个命名进程 ),这个命名对象可以接收相应
的事件并且处理,在下面的代码中event_就相当于
gen _.
13.2. 代码
event_or_


13.3. 使用方法
(ej@)1> event_handler:make(errors).
true
(ej@)2> event_handler:event(errors, hi).
{event,hi}
fun ret

is:void
(ej@)3>motor_controller:add_event_handler().
{add,#Fun}
(ej@)4> event_handler:event(errors, hi).
motor_controller ignored event: hi
{event,hi}
fun ret

is:void
13.4.
?
event_和motor_代码分析

event_分析
? make函数(14行)注册一个名称为Name的进程,进程中执行 的函数为
my_handler(?).
? add_handler(?)(17行)改变my_handler函数中的参数(函数指针)。
? event(?)(20行)向Name进程发送消息。

? motor_分析
? add_event_handler(?)调用event_中的add_handler函数。
? controller(?)为add_event_handler传递给add_handler的”函数指
针”。

_fsm
14.1. 简介
有限状态机可以被描述为以下的关系:
State(S) x Event(E) -> Action(A), State(S’)
假如我们在状态S,此时发生了一个E事件,接下来应该 执行动作A,然后改变状
态机的状态至S’.
14.2. 代码
code_
14.3.

使用方法、
1> c(code_lock).
{ok,code_lock}
2> code_lock:start([1,2,3]).
{ok,<0.36.0>}
3> code_lock:button(1).
Now the code you input is: [1]
ok
4> code_lock:button(2).


Now the code you input is: [1,2]
ok
5> code_lock:button(3).
Now the code you input is: [1,2,3]
ok
6> code_lock:button(1).
Now the code you input is: [1]
ok
7> code_lock:button(2).
Now the code you input is: [1,2]
ok
8> code_lock:button(2).
Now the code you input is: [1,2,2]
ok
Wrong Start
14.4.
code_文件解释
参见代码注释。
15.监督树
15.1. 简介
监督树是监督一个或者多个其它进程的进程,监督进程一般负责启动挂掉的 进程。
在启动子进程的时候可以设置重启被监督进程的策略..
15.2. 代码

sellaprime_a_me_

lib_
lib_

my_alarm_



sellaprime_


15.3. 使用方法
由于指令比较多这里只列出指令:
? erl -boot start_sasl -config (启动erlang)
?
?
?
?
?
sellaprime_supervisor:start_ in_shell_for_testing().
area_server:area({square,10}).
area_server:area({rectange,10, 20}).
area_server:area({square, 25}).
prime_server:new_prime(20).
说明:
start_sasl启动标志建立一个适合运行产品级的的系统,(System
Architecture Support Library, SASL)将会关注于错误日志,过载保护等等。


注意修改中的日志文件路径。
15.4. sellaprime_文件解释
15.4.1. start_in_she ll_for_testing(?)开启一个监督进程,并且将调用进程与
此监督进程分离。
15.4.2. init([]).(27行)启动两个子监督进程。关于开启子进程中进程列表中每
一项的意义参见:erlang程序设计中文版P298, 英文版P353。

16.热代码切换
16.1.

代码
e__name_

16.2.
使用方法
(ej@)1> server3:start(name_server, name_server1).
true
(ej@)2> name_server1:add(joe, ).
ok
(ej@)3> name_server1:add(helen, ).
ok
(ej@)4> server3:swap_code(name_server, new_name_server).
ack
(ej@)5> new_name_server:all_names().
[joe,helen]
16.3.

文件解释
略。
17.完整的OTP应用程序

17.1. 代码
在上一节监督树的那几个文件的基础上在加上以下文件:
sellaprime_

17.2. 使用方法
切换测试文件所在路径执行命令:erl -boot start_sasl -config ,
然后执行一下erlang指令:
1> application:loaded_applications().
[{kernel,
{sasl,
{stdlib,
2> application:load(sellaprime).
ok


3> application:loaded_applications().
[{kernel,
{sasl,
{stdlib,
{sellaprime,
4> application:start(sellaprime).
*** my_alarm_handler init:{xyz,{alarm_handler,[]}}
area_server starting
prime_server start_link
prime_server starting
ok
5> application:stop(sellaprime).
prime_server stopping
area_server stopping

=INFO REPORT==== 1-Feb-2012::10:21:50 ===
application: sellaprime
exited: stopped
type: temporary
ok
6> application:loaded_applications().
[{kernel,
{sasl,
{stdlib,
{sellaprime,
7> application:unload(sellaprime).
ok
8> application:loaded_applications().
[{kernel,
{sasl,
{stdlib,
说明: 第一条指令检查erlang运行系统中正在运行的应用程序。
第二条指令加载了应用程序,加载动作会载入所有的代码,但不会启
动应用程序。
第四条指令启动了应用程序。
第五条指令将这个应用程序停止。
第七条指令卸载sellaprime应用程序。
17.3.
文件解释
此文件包含了应用程序的说明,已经此应用程序要加载的模块等应用程序加载相关
的信息。

complain是什么意思中文-免费的自学软件网站


爱莫能助什么意思-峭怎么读


institution-生活的拼音


自主是什么意思-ticket是什么意思中文


2020年世界大学排名-斤两


原子核裂变-石灰的化学式


棒杀-袖扣的用法


解数-funny什么意思



本文更新与2020-10-25 04:46,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/424609.html

erlang基础知识集锦的相关文章