Erlang Thursday – c:pid/3

今天的Erlang Thursday我们简单讲讲 c:pid/3.

c:pid/3 三个入参分别是一个pid的三个部分的整数值,返回值的类型是与入参值对应的Pid类型。

我们调用 self 函数来得到当前的pid,然后我们可以调用 c:pid/3 和 self 返回的值进行比较。

1
2
3
4
5
6
self().
% <0.42.0>
c:pid(0, 42, 0).
% <0.42.0>
self() =:= c:pid(0, 42, 0).
% true

这个函数有什么用呢?有时候当我们检测一个在线系统的时候,在Erlang里有些调用是需要Pid类型的入参而不只是pid的三个整数值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
c:regs().
%
% ** Registered procs on node nonode@nohost **
% Name Pid Initial Call Reds Msgs
% application_controlle <0.7.0> erlang:apply/2 463 0
% code_server <0.19.0> erlang:apply/2 128774 0
% erl_prim_loader <0.3.0> erlang:apply/2 163760 0
% error_logger <0.6.0> gen_event:init_it/6 220 0
% file_server_2 <0.18.0> file_server:init/1 448 0
% global_group <0.17.0> global_group:init/1 59 0
% global_name_server <0.13.0> global:init/1 51 0
% inet_db <0.16.0> inet_db:init/1 206 0
% init <0.0.0> otp_ring0:start/2 3398 0
% kernel_safe_sup <0.27.0> supervisor:kernel/1 58 0
% kernel_sup <0.11.0> supervisor:kernel/1 49109 0
% rex <0.12.0> rpc:init/1 35 0
% standard_error <0.21.0> erlang:apply/2 9 0
% standard_error_sup <0.20.0> supervisor_bridge:standar 41 0
% user <0.24.0> group:server/3 36 0
% user_drv <0.23.0> user_drv:server/2 17940 0
%
% ** Registered ports on node nonode@nohost **
% Name Id Command
% ok
erlang:is_process_alive(c:pid(0, 6, 0)).
% true

让我们以正常的方式给这个函数传入一些让其异常的值看看它会发生什么?

1
2
3
4
5
6
7
c:pid(0, 0, 0).
% <0.0.0>
c:pid(111110, 0, 1111110).
% ** exception error: bad argument
% in function list_to_pid/1
% called as list_to_pid("<111110.0.1111110>")
% in call from c:pid/3 (c.erl, line 424)

像<0.0.0>这样的pid是有效的pid,但是传入无效的pid,函数抛出异常,从异常信息里我们看到它尝试调用 list_to_pid 。

让我们快速看看 list_to_pid 。

1
2
3
4
erlang:list_to_pid("<0.42.0>").
% <0.42.0>
c:pid(0, 42, 0) =:= erlang:list_to_pid("<0.42.0>").
% true

看起来 c:pid/3 是一个 list_to_pid 的封装函数,它把pid的三个部分的整数值构建成一个字符串,然后调用 list_to_pid 来得到一个 Pid 类型的值。

原文链接: https://www.proctor-it.com/erlang-thursday-c-pid-3/