erlang程序设计中文版读书笔记
个人读书笔记,我看书走马观花,侧重点比较诡异,大多流水记录,可读性不大。
入门
- erl shell,执行最后要加个
.
- 变量不变, 强制大写开头
- = 表示模式匹配,不是常规语言中的
赋值
- 变量多次赋值,就会
exception error: no match of right hand side value
- 变量多次赋值,就会
- 抛弃副作用,拥抱并行化
- erlang中原子,表示
非数字常量
(很诡异的歧义,注意)- 小写字母开头可以用
_
和@
连接
- 小写字母开头可以用
- 每个表达式都必须有值
- 元组与元组展开。和python c++类似
- 列表,以及列表头尾快捷操作(有点像模板元)
- 字符串
- 就是整数列表,必须双引号,需要大写字母开头
- $i表示字符i
顺序型编程
-
一切都是表达式,一切表达式都有值
- 所以说ruby perl rust那种最后留一个值做返回值的做法算是函数式风格的求值?
- 模块 和python/js类似 ,-module(module_name) -export(func_name) 导出 -import(module_name, [func_name])
- 函数
- 同名不同目,也就是重载支持,可以,只做helper
- func,也就是lambda,支持作为参数以及返回
- 控制流对应成匹配,循环,那就用列表生成
-
if/case都是case模式匹配
-
异常
- try-catch 也是case模式的,丢失细节
- erlang:error
sqrt(X) when X < 0 -> erlang:error({squareRootNegativeArgument, X}); sqrt(X) -> math:sqrt(X)
有点像c++ 的constraint
-
调用栈
- erlang:get_stacktrace()
-
BIT 内建函数 buildin
- tuple_to_list
- 二进制流 «“cat”»
-
属性-SomeTag()
-
块表达式,begin end包起来整体求值
-
宏,引用,这套和c有点像
-
进程字典,每个进程有自己的私有数据
- 运行时别用。当成元数据保存还行
-
引用,全局唯一的值。有点像全局变量。
- 下划线变量 用完就扔,调试用
编译运行
-
指定搜索路径
@spec code:add_patha(Dir) => true |{error, badd_directory} @spec code:add_pathz(Dir) => true |{error, badd_directory}
-
编译运行与脚本运行
- 脚本需要main入口,编译直接调用函数就行
- 也得写makefile(2020了还手写吗)
并发
-
并发原语
-
spawn启动一个进程,返回pid
-
a ! b
表示发送 - receive 可以带超时限制
- 同步?
-
进程管理 -> 注册进程
-
一个echo
start() -> spawn(fun() -> loop([]) end). rpc(Pid, Request) -> Pid ! {self(), Request}, receive {Pid, Response} -> Response end. loop(X) -> receive Any -> io:format("Received:~p~n", [Any]), loop(x) end.
- 用到了尾递归技术,不能有多余的函数调用,不然不能复用栈空间、
-
-
MFA 启动进程,
spawn(Mod, FuncName, Args)
动态更新升级?
并发编程中的错误处理
-
链接进程
进程依赖的强绑定,强制信号通知,这些东西在c是不强制的
-
on_exit 这东西c++也有,erlang的on_exit还可以hook已有 的进程,很妙
-
天生分布式,进程的错误托管给别的进程来处理
-
错误处理的三种基础盖面
- 进程链接
- 退出信号
- 系统进程信息
-
捕获退出的编程模式
- 不在乎进程是否崩溃
Pid = spawn(func() -> ...end)
- 进程崩溃我也崩溃,进程链接
Pid = spwan_link(fun() -> ...end)
-
进程崩溃我处理错误
... process_flag(trap_exit, true), Pid = spwan_link(fun() -> ...end), ... loop(...).
loop(State) -> receive {‘EXIT’, SomePid, Reason} -> %% do something with the error loop(State); … end
- 不在乎进程是否崩溃
-
错误处理原语
- spawn_link
- process_flag
- link
- unlink
- exit
-
工人-监工模型
-
monitor,守护进程
keep_alive(Name, Fun) -> register(Name, Pid = spawn(Fun)), on_exit(Pid, fun(_Why) -> keep_alive(Name, Fun) end).
分布式编程
- rpc
- global名称注册函数/分布式锁定功能
- cookies设置
基于socket
接口技术
- open_port
文件编程
没啥说的
套接字编程
没啥说的
ETS/DETS
OTP
监控树和supervisor
多核问题
- 状态不可变,并行化
- MapReduce
更有效率
- 大量进程 但不要太多
- 避免副作用
- 避免顺序瓶颈
- 少量消息,大量计算
ref
-
关于erlang进程系统的资料
- https://www.iteye.com/blog/jzhihui-1482175
- https://www.erlang-factory.com/upload/presentations/558/efsf2012-whatsapp-scaling.pdf
- https://blog.yufeng.info/archives/2615
- https://www.zhihu.com/question/24732869
-
希望能看懂https://github.com/cbd/edis/blob/master/src/edis_sup.erl
-
https://www.cnblogs.com/me-sa/ 这人写的erlang博客不错,讲真看这本书不如看他的博客