Erlang

1、pid结构<A.B.C>

  • A:节点号(0为本地节点,其他为远程节点)
  • B:进程号的前15位(进程表的索引)
  • C:进程号的16-18位(与B的进程号相同)

2、spawn与spawn_link

  • 在实际代码中先spawn然后link与spawn_link是相同的,但在时效是不等同的
  • 在spawn一个进程时在初始化死亡(start或者init操作),在link之前死亡,则链接进程将永远不会收到通知,也不会有错误消息

3、Erlang进程映射到内核线程

  • 非SMP:有一个调度程序(OS线程),它执行所有Erlang进程,取自可运行进程池(即那些未被例如阻塞的进程receive)
  • SMP:有K个调度程序(OS线程,K通常是许多CPU内核),它们从共享进程队列执行Erlang进程。它是一个简单的FIFO队列(带有锁,允许从多个OS线程同时访问)
  • R13B以上版本中的SMP:将有K个调度程序(如前所述)从多个进程队列执行Erlang进程。每个调度程序都有自己的队列,因此将添加从一个调度程序到另一个调度程序的进程迁移逻辑。此解决方案将通过避免共享进程队列中的过度锁定来提高性能

4、Beam(Erlang VM)理解

Erlang VM作为一个OS进程运行。默认情况下,它为每个核心运行一个OS线程,以实现机器的最大利用率。启动VM时,可以设置线程数以及它们运行的​​核心数。Erlang进程完全由Erlang VM 实现,并且与OS进程或OS线程无关。因此,即使您运行的是超过一百万个进程的Erlang系统,它仍然只有一个操作系统进程和每个核心一个线程。因此,在这个意义上,Erlang VM是一个“进程虚拟机”,而Erlang系统本身就像一个操作系统,Erlang进程具有与OS进程非常相似的属性,例如隔离。实际上有一个基于BEAM的Erlang VM,它运行在裸机上,实际上是一个独立的操作系统

5、查询进程状态

sys:get_status/1

6、Erlang并发模型

  • 轻量级并发:应该能够有效地为应用程序创建任意数量的进程,并且应该能够在必要时有效地创建和删除它们。这意味着进程轻而小,无需使用进程池来节省时间
  • 异步通信:所有进程通信都是通过异步消息传递,就是这样,没有别的
  • 错误处理:与轻量级并发和异步消息相同的方式是构建并发系统错误处理的基础,这对于构建健壮的系统至关重要。这个原语与并发交互,是Erlang并发模型的一部分
  • 过程隔离:进程之间根本没有共享状态,唯一的通信方式是通过消息传递。这对于能够构建健壮的系统至关重要,因为它允许进程崩溃而不会破坏其他进程。当然,他们可能会收到进程因错误处理机制而崩溃的信息,但崩溃将永远不会在其他进程中创建不一致的状态。这样做的必然结果是没有共享数据

7、区分字符串与列表

io_lib:printable_list/1和io_lib:printable_unicode_list/1

8、简化消息传递VM底层操作

  • 在发送过程中分配目标内存空间(环境)
  • 将邮件复制到该内存空间
  • 对目标进程执行外部锁定
  • 将邮件链接到邮箱链接列表
  • 释放目标进程上的外部锁定

9、Erlang中process_flag(trap_exit, true)

  • 不在乎孩子过程是否死亡 spawn(…)
  • 子进程崩溃,也跟着崩溃 spawn_link(…)
  • 子进程终止,收到一条消息 process_flag(trap_exit, true),spawn_link(…)

10、二进制转换为16进制

io:format(“<<s>>n”, [[io_lib:format(“~2.16.0B”,[X]) <> <= <<255,16>> ]]).

11、内存泄漏

  • 原子表填满(创建太多不同的原子)
  • ETS或Mnesia表不是垃圾回收(不删除旧的未使用的元素)
  • 进程内存不足(产生太多进程)
  • 创建了太多二进制文件(可能会保留对旧二进制文件的未使用引用)

12、术语比较

  • 在Erlang中,任何术语都可以与任何其他术语进行比较:number < atom < reference < fun < port < pid < tuple < map < nil < list < bit string
  • 在Erlang中就出现了nil > 0为true

13、start_link/3与start_link/4

ServerName参数会先查找一遍是否有同名的进程存在,有就会产生{error,{already_started,Pid}}的提示

14、erlang:now()和os:timestamp()

erlang:now()获取的是erlang虚拟机时钟,os:timestamp()获取的是操作系统时间

15、gen_server:cast和erlang:send()

gen_server:cast调用的就是erlang:send()函数,消息为{‘$gen_cast’,Request},但是加上了no_connect。如果没有连上,那么返回false

16、查询epmd可见的节点

  • EpmdModule = net_kernel:epmd_module().
  • EpmdModule:names().

17、获取已连接节点及其端口的列表

  • erlang:system_info(dist).
  • erlang:system_info(dist_ctrl).

18、进程与线程

进程和线程都是独立的执行序列。典型的区别在于(同一进程的)线程在共享内存空间中运行,而进程在不同的内存空间中运行。