处理 | Process
处理
使用过程和过程字典的方便性。
除了本模块中可用的功能外,Kernel
模块公开和自动导入一些与可通过以下函数提供的进程相关的基本功能:
Kernel.spawn/1
和Kernel.spawn/3
Kernel.spawn_link/1
和Kernel.spawn_link/3
Kernel.spawn_monitor/1
和Kernel.spawn_monitor/3
Kernel.self/0
Kernel.send/2
摘要
类型
spawn_opt()spawn_opts()
功能
alive?(pid)
告诉给定进程是否是活动的。
cancel_timer(timer_ref, options \ [])
取消返回的计时器 send_after/3
delete(key)
key
从流程字典中删除给定的内容
demonitor(monitor_ref, options \ [])
恶魔监视器通过给定的标识符来识别 reference
exit(pid, reason)
用给定的reason
to 发送一个退出信号pid
flag(flag, value)
设置给定flag
到value
用于调用进程
flag(pid, flag, value)
设置给定flag
到value
对于给定的过程pid
get()
返回流程字典中的所有键值对。
get(key, default\nil)
返回给定值的值。key
在流程字典中,或default
如果key
未设置
get_keys()
返回流程字典中的所有键。
get_keys(value)
返回进程字典中具有value
group_leader()
返回调用进程的组领导的PID。
group_leader(pid, leader)
设置给定组的组长。pid
到leader
hibernate(mod, fun_name, args)
将调用进程置于“休眠”状态。
info(pid)
返回有关由pid
,或返回nil
如果进程没有活动
info(pid, spec)
返回有关由进程标识的进程的信息pid
,或返回nil
进程没有活动的进程
link(pid_or_port)
创建调用进程和给定项目(进程或端口)之间的链接
list()
返回对应于本地节点上当前存在的所有进程的PID列表。
monitor(item)
开始监视给定的item
从调用过程中
put(key, value)
商店给定key
- value
一对进程字典
read_timer(timer_ref)
读取由...send_after/3
创建的计时器
register(pid_or_port, name)
在给定的情况pid_or_port
下注册给定的name
registered()
返回已使用register/2
send(dest, msg, options)
向给定进程发送消息。
send_after(dest, msg, time, opts \ [])
发送msg
到毫秒dest
后time
sleep(timeout)
为当前进程安排当前进程 timeout
sleep(timeout)
根据给定的选项生成给定的函数。
spawn(mod, fun, args, opts)
fun
从模块中产生给定的函数mod
,args
根据给定的选项传递给定的函数
unlink(pid_or_port)
删除调用进程和给定项目(进程或端口)之间的链接
unregister(name)
移除注册name
,与PID或端口标识符关联。
whereis(name)
返回在name
或nil
如果名称未注册
类型
spawn_opt()
spawn_opt ::
:link |
:monitor |
{:priority, :low | :normal | :high} |
{:fullsweep_after, non_neg_integer} |
{:min_heap_size, non_neg_integer} |
{:min_bin_vheap_size, non_neg_integer}
spawn_opts()
spawn_opts() :: [spawn_opt]
功能
alive?(pid)
alive?(pid) :: boolean
指示给定进程是否处于活动状态。
如果标识的进程pid
存在(即,它不退出并且还没有退出),则该函数返回true
。否则,它返回false
。
pid
必须引用在本地节点上运行的进程。
编译器插入。
cancel_timer(timer_ref, options \ [])
cancel_timer(reference, options) ::
non_neg_integer |
false |
:ok when options: [async: boolean, info: boolean]
取消返回的计时器send_after/3
。
当结果是整数时,它表示计时器过期前的毫秒时间。
当结果是false
,对应于timer_ref
找不到。这可能是因为计时器过期了,因为它已经被取消了,或者是因为timer_ref
从来不和计时器对应。
即使计时器已经过期并且消息已经发送,此函数也不会告诉您超时消息是否已到达其目的地。
备选方案
:async
- (boolean)何时false
,取消请求是同步的。何时true
,取消请求是异步的,意味着取消定时器的请求被发出并立即:ok
返回。默认为false
。
:info
- (boolean)是否返回有关正在取消的定时器的信息。当:async
选择是false
和:info
是true
,则整数或false
(如上述)被返回。如果:async
是false
和:info
是false
,:ok
被返回。如果:async
是true
和:info
是true
,则在执行取消操作时,表单中的消息{:cancel_timer, timer_ref, result}
(其中result
是整数或false
类似于上述内容)会发送给此函数的调用者。如果:async
是true
和:info
是false
,不发送任何消息。默认为true
。
编译器插入。
delete(key)
delete(term) :: term | nil
删除给定的key
从过程字典。
返回下得值key
的进程字典,或者nil
如果key
没有被存储在进程字典。
实例
Process.put(:comments, ["comment", "other comment"])
Process.delete(:comments)
#=> ["comment", "other comment"]
Process.delete(:comments)
#=> nil
demonitor(monitor_ref, options \ [])
demonitor(reference, options :: [:flush | :info]) :: boolean
恶魔监视器通过给定的标识符来识别reference
。
如果monitor_ref
是调用进程通过调用获得的引用monitor/1
,则该监视被关闭。如果监控已关闭,则不会发生任何事情。
查看:erlang.demonitor/2
更多信息。
编译器插入。
exit(pid, reason)
exit(pid, term) :: true
用给定的reason
to 发送一个退出信号pid
。
如果reason
除了:normal
或以外的任何术语,则以下行为适用:kill
:
- 如果
pid
不陷阱退出,pid
将退出给定reason
。
2. 如果pid
陷阱退出,则退出信号被转换为消息{:EXIT, from, reason}
并传递到消息队列中pid
。
如果reason
是原子:normal
,pid
则不会退出(除非pid
是调用过程,在这种情况下它将随原因退出:normal
)。如果陷入退出,退出信号被转换为消息{:EXIT, from, :normal}
并传递到其消息队列。
如果reason
是原子:kill
,即如果Process.exit(pid, :kill)
被调用,则发送无法接收的退出信号,pid
其将无条件地退出:killed
。
编译器插入。
实例
Process.exit(pid, :kill)
#=> true
flag(flag, value)
flag(:trap_exit, boolean) :: boolean
flag(:sensitive, boolean) :: boolean
flag(:save_calls, 0..10000) :: 0..10000
flag(:priority, priority_level) :: priority_level
flag{:monitor_nodes, term}, term) :: term
flag(:monitor_nodes, term) :: term
flag(:min_heap_size, non_neg_integer) :: non_neg_integer
flag(:min_bin_vheap_size, non_neg_integer) :: non_neg_integer
flag(:message_queue_data, :erlang.message_queue_data) :: :erlang.message_queue_data
flag(:max_heap_size, heap_size) :: heap_size
flag(:error_handler, module) :: module
设置给定flag
到value
用于呼叫进程。
返回旧的值flag
。
查看:erlang.process_flag/2
更多信息。
需要注意的是flag
价值观:max_heap_size
和:message_queue_data
仅可自OTP 19。
编译器插入。
flag(pid, flag, value)
flag(pid, :save_calls, 0..10000) :: 0..10000
设置给定flag
到value
对于给定的过程pid
。
返回旧的值flag
。
ArgumentError
如果pid
不是本地进程,则会引发此问题。
允许flag
的值只是允许的值的一个子集flag/2
,即:save_calls
。
查看:erlang.process_flag/3
更多信息。
编译器插入。
get()
get() :: [{term, term}]
返回流程字典中的所有键值对。
编译器插入。
get(key, default \ nil)
get(term, default :: term) :: term
返回给定值key
的过程中字典,或者default
如果key
未设置。
get_keys()
get_keys() :: [term]
返回流程字典中的所有键。
编译器插入。
get_keys(value)
get_keys(term) :: [term]
返回具有给定值的流程字典中的所有键value
。
编译器插入。
group_leader()
group_leader() :: pid
返回调用进程的组领导的PID。
编译器插入。
group_leader(pid, leader)
group_leader(pid, leader :: pid) :: true
设置给定的组长pid
来leader
。
通常情况下,当从某个shell启动的进程应该具有组长以外的组时,就会使用:init
。
编译器插入。
hibernate(mod, fun_name, args)
hibernate(module, atom, list) :: no_return
将调用进程置于“休眠”状态。
调用进程处于等待状态,其内存分配尽可能减少,如果进程在不久的将来不会收到任何消息,这将非常有用。
查看:erlang.hibernate/3
更多信息。
编译器插入。
info(pid)
info(pid) :: keyword
返回有关由进程标识的进程的信息pid
,或返回nil
进程没有活动的进程。
仅用于调试信息。
查看:erlang.process_info/1
更多信息。
info(pid, spec)
info(pid, atom | [atom]) ::
{atom, term} |
[{atom, term}] |
nil
返回有关由进程标识的进程的信息pid
,或返回nil
进程没有活动的进程。
查看:erlang.process_info/2
更多信息。
info(pid, spec)
link(pid | port) :: true
创建调用进程和给定项目(进程或端口)之间的链接。
链接是双向的。链接的流程可以通过使用取消关联unlink/1
。
如果这样的链接已经存在,这个函数什么也不做,因为在两个给定的进程之间只能有一个链接。如果一个进程试图创建一个自己的链接,什么都不会发生。
当两个进程链接时,每个进程都会收到来自另一个进程的退出信号(另请参见exit/2
)。我们假设pid1
并pid2
链接。如果pid2
以其他原因退出:normal
(这也是进程完成其工作时使用的退出原因)并且pid1
没有陷阱退出(请参阅参考资料flag/2
),那么pid1
退出时将以相同的原因退出,pid2
并转而向所有其他退出信号发出退出信号关联流程。在pid1
陷阱出口时的行为描述如下exit/2
。
查看:erlang.link/1
更多信息。
编译器插入。
list()
list() :: [pid]
返回对应于本地节点上当前存在的所有进程的PID列表。
请注意,如果某个进程正在退出,则认为该进程存在但不存在。这意味着对于这样的过程,alive?/1
将返回,false
但其PID将成为由该函数返回的PID列表的一部分。
查看:erlang.processes/0
更多信息。
编译器插入。
monitor(item)
monitor(pid | {reg_name :: atom, node :: atom} | reg_name :: atom) :: reference
开始监视item
调用进程中的给定内容。
一旦被监控的进程死亡,将以下列形式向监控进程发送消息:
{:DOWN, ref, :process, object, reason}
其中:
ref
是此函数返回的监视器引用;
object
是pid
监视的过程(如果监视PID)或{name, node}
(如果监视远程或本地名称);
reason
是退出原因。
见监测的必要性举个例子。见:erlang.monitor/2
想了解更多信息。
编译器插入。
put(key, value)
put(term, term) :: term | nil
商店给定key
- value
一对进程字典。
此函数的返回值是以前存储在该值下的值key
,或者nil
如果没有值存储在该值下面key
。
实例
# Assuming :locale was not set
Process.put(:locale, "en")
#=> nil
Process.put(:locale, "fr")
#=> "en"
read_timer(timer_ref)
read_timer(reference) :: non_neg_integer | false
读取由send_after/3
创建的计时器。
当结果是一个整数时,它表示以毫秒为单位的时间,直到定时器到期。
如果结果是false
,则timer_ref
找不到相应的计时器。这可能是因为定时器过期,因为它已经被取消,或者因为timer_ref
从来没有对应过一个定时器。
即使计时器过期并且发送了消息,该功能也不会告诉您超时消息是否已到达目的地。
编译器插入。
register(pid_or_port, name)
register(pid | port, atom) :: true
在给定的情况pid_or_port
下注册给定的name
。
name
必须是原子,然后可以在发送消息时使用,而不是PID /端口标识符Kernel.send/2
。
register/2
将ArgumentError
在下列任何情况下失败:
- PID/端口在本地不存在,并且是活动的。
- 该名称已被注册
- 在
pid_or_port
已经根据不同登记name
以下名称是保留的,不能分配给进程或端口:
nil
false
true
:undefined
registered()
registered() :: [atom]
返回已使用注册的名称列表register/2
。
编译器插入。
send(dest, msg, options)
send(dest, msg, [option]) ::
:ok |
:noconnect |
:nosuspend when dest: pid | port | atom | {atom, node}, msg: any, option: :noconnect | :nosuspend
向给定进程发送消息。
备选方案
:noconnect
- 使用时,如果发送消息需要自动连接到另一个节点,则不发送消息并返回:noconnect
。
:nosuspend
- 使用时,如果发送邮件会导致发件人被暂停,则邮件不会发送并返回:nosuspend
。
否则,消息将被发送并:ok
返回。
实例
iex> Process.send{:name, :node_that_does_not_exist}, :hi, [:noconnect])
:noconnect
编译器插入。
send_after(dest, msg, time, opts \ [])
send_after(pid | atom, term, non_neg_integer, [option]) :: reference when option: {:abs, boolean}
发送msg
到毫秒dest
后time
。
如果dest
是PID,它必须是本地进程的PID,无论是死还是活。如果dest
是原子,它必须是在交付时查找的注册过程的名称。如果名称不涉及过程,则不会产生错误。
这个函数返回一个定时器引用,它可以被读取read_timer/1
或取消cancel_timer/1
。
如果给定dest
的PID不存在或给定的PID退出,定时器将自动取消。请注意,定时器在dest
原子时不会自动取消(因为原子分辨率是在交付时完成的)。
编译器插入。
备选方案
:abs
- (布尔值)时false
,time
作为相对于当前时间单调进行处理。当true
,time
是在该二郎单调时间的绝对值msg
应该交付给dest
。要阅读更多关于Erlang单调时间和其他与时间有关的概念,请查看System
模块的文档。默认为false
。
实例
timer_ref = Process.send_after(pid, :hi, 1000)
sleep(timeout)
sleep(timeout) :: :ok
为当前进程安排当前进程timeout
。
timeout
是以整数或原子睡眠的毫秒数:infinity
。当:infinity
给出时,当前进程将永久休眠,而不消耗或回复消息。
谨慎使用此功能
。几乎所有sleep/1
在Elixir中都会使用的情况下,可能会有更准确,更快,更准确的方式来实现消息传递。
例如,如果您正在等待某个进程执行某些操作,则最好将此类操作的进度与消息进行通信。
换句话说,不要
*
Task.start_link fn ->
do_something()
...
end
# Wait until work is done
Process.sleep(2000)
但做
*
parent = self()
Task.start_link fn ->
do_something()
send parent, :work_is_done
...
end
receive do
:work_is_done -> :ok
after
30_000 -> :timeout # Optional timeout
end
像上面这样的案子,Task.async/1
和Task.await/2
都是首选。
同样,如果您正在等待进程终止,则监视该进程而不是休眠。不要
*
Task.start_link fn ->
...
end
# Wait until task terminates
Process.sleep(2000)
相反做
*
{:ok, pid} =
Task.start_link fn ->
...
end
ref = Process.monitor(pid)
receive do
{:DOWN, ^ref, _, _, _} -> :task_is_down
after
30_000 -> :timeout # Optional timeout
end
spawn(fun, opts)
spawn((() -> any), spawn_opts) :: pid | {pid, reference}
根据给定的选项生成给定的函数。
结果取决于给定的选项。特别是,如果:monitor
作为选项,它将返回一个包含PID和监视引用的元组,否则只返回生成的进程PID。
更多选择可用; 为可用选项检查的综合列表:erlang.spawn_opt/4
。
编译器插入。
spawn(mod, fun, args, opts)
spawn(module, atom, list, spawn_opts) ::
pid |
{pid, reference}
fun
从模块中产生给定的函数mod
,args
根据给定的选项传递给定的函数。
结果取决于给定的选项。特别是,如果:monitor
作为选项给出,它将返回一个包含PID和监视参考的元组,否则返回派生过程PID。
它也接受额外的选项,查看可用选项列表:erlang.spawn_opt/4
。
编译器插入。
unlink(pid_or_port)
unlink(pid | port) :: true
删除调用进程和给定项目(进程或端口)之间的链接。
如果没有这样的链接,这个函数什么都不做。如果pid_or_port
不存在,这个函数不会产生任何错误,而且什么也不做。
这个函数的返回值总是true
。
查看:erlang.unlink/1
更多信息。
编译器插入。
unregister(name)
unregister(atom) :: true
删除已注册的name
,与PID或端口标识符关联的。
失败ArgumentError
如果名称未注册到任何PID或端口。
编译器插入。
whereis(name)
whereis(atom) :: pid | port | nil
返回根据name
或nil
名称未注册注册的PID或端口标识符。
查看:erlang.whereis/1
更多信息。