Erlang进程基础 #
一、进程概述 #
Erlang进程是轻量级的并发单元,是Erlang并发模型的核心。
1.1 进程特点 #
- 轻量级(初始约2KB栈空间)
- 创建成本低
- 没有共享内存
- 通过消息传递通信
- 支持数十万级并发
1.2 进程与线程比较 #
| 特性 | Erlang进程 | 操作系统线程 |
|---|---|---|
| 内存 | 约2KB | 约1MB |
| 创建成本 | 极低 | 较高 |
| 切换成本 | 极低 | 较高 |
| 通信方式 | 消息传递 | 共享内存 |
二、创建进程 #
2.1 spawn/1 #
erlang
-module(spawn_basic).
-export([demo/0]).
demo() ->
Pid = spawn(fun() ->
io:format("Hello from process ~p~n", [self()])
end),
io:format("Spawned process: ~p~n", [Pid]).
2.2 spawn/3 #
erlang
-module(spawn_module).
-export([demo/0, loop/0]).
demo() ->
Pid = spawn(?MODULE, loop, []),
io:format("Spawned process: ~p~n", [Pid]).
loop() ->
receive
stop -> ok;
Msg ->
io:format("Received: ~p~n", [Msg]),
loop()
end.
2.3 spawn_link/1 #
erlang
-module(spawn_link_demo).
-export([demo/0, worker/0]).
demo() ->
process_flag(trap_exit, true),
Pid = spawn_link(fun worker/0),
io:format("Spawned linked process: ~p~n", [Pid]),
receive
{'EXIT', Pid, Reason} ->
io:format("Process exited: ~p~n", [Reason])
end.
worker() ->
timer:sleep(1000),
exit(normal).
2.4 spawn_monitor/1 #
erlang
-module(spawn_monitor_demo).
-export([demo/0]).
demo() ->
{Pid, Ref} = spawn_monitor(fun() ->
timer:sleep(1000),
exit(normal)
end),
io:format("Spawned monitored process: ~p~n", [Pid]),
receive
{'DOWN', Ref, process, Pid, Reason} ->
io:format("Process down: ~p~n", [Reason])
end.
三、进程标识符 #
3.1 Pid格式 #
erlang
-module(pid_format).
-export([demo/0]).
demo() ->
Self = self(),
io:format("Self: ~p~n", [Self]),
io:format("Is pid: ~p~n", [is_pid(Self)]),
io:format("Is process alive: ~p~n", [is_process_alive(Self)]).
Pid格式:<NodeID.ProcessID.Serial>
3.2 Pid操作 #
erlang
-module(pid_ops).
-export([demo/0]).
demo() ->
Pid = self(),
List = pid_to_list(Pid),
io:format("Pid to list: ~p~n", [List]),
NewPid = list_to_pid(List),
io:format("List to pid: ~p~n", [NewPid]),
io:format("Equal: ~p~n", [Pid =:= NewPid]).
四、进程状态 #
4.1 进程字典 #
erlang
-module(process_dict).
-export([demo/0]).
demo() ->
put(key1, value1),
put(key2, value2),
io:format("Get key1: ~p~n", [get(key1)]),
io:format("Get key2: ~p~n", [get(key2)]),
io:format("Get all: ~p~n", [get()]),
erase(key1),
io:format("After erase key1: ~p~n", [get()]).
4.2 进程标志 #
erlang
-module(process_flags).
-export([demo/0]).
demo() ->
OldTrapExit = process_flag(trap_exit, true),
io:format("Old trap_exit: ~p~n", [OldTrapExit]),
OldPriority = process_flag(priority, high),
io:format("Old priority: ~p~n", [OldPriority]).
常用进程标志:
| 标志 | 说明 |
|---|---|
trap_exit |
捕获EXIT信号 |
priority |
进程优先级 |
min_heap_size |
最小堆大小 |
max_heap_size |
最大堆大小 |
message_queue_data |
消息队列数据 |
4.3 进程信息 #
erlang
-module(process_info).
-export([demo/0]).
demo() ->
Pid = self(),
Info = process_info(Pid),
io:format("Process info: ~p~n", [Info]),
Messages = process_info(Pid, messages),
io:format("Messages: ~p~n", [Messages]),
Memory = process_info(Pid, memory),
io:format("Memory: ~p~n", [Memory]).
五、进程注册 #
5.1 注册进程 #
erlang
-module(register_process).
-export([start/0, loop/0, send/1, stop/0]).
start() ->
Pid = spawn(?MODULE, loop, []),
register(my_server, Pid),
{ok, Pid}.
loop() ->
receive
{request, From, Msg} ->
From ! {response, Msg},
loop();
stop ->
ok
end.
send(Msg) ->
my_server ! {request, self(), Msg},
receive
{response, Response} -> {ok, Response}
after 5000 -> {error, timeout}
end.
stop() ->
my_server ! stop,
ok.
5.2 查询注册 #
erlang
-module(register_query).
-export([demo/0]).
demo() ->
case whereis(my_server) of
undefined -> io:format("Process not registered~n");
Pid -> io:format("Process pid: ~p~n", [Pid])
end,
Registered = registered(),
io:format("Registered processes: ~p~n", [Registered]).
六、进程链接 #
6.1 link #
erlang
-module(link_demo).
-export([demo/0, worker/0]).
demo() ->
process_flag(trap_exit, true),
Pid = spawn(fun worker/0),
link(Pid),
io:format("Linked to: ~p~n", [Pid]),
receive
{'EXIT', Pid, Reason} ->
io:format("Process exited: ~p~n", [Reason])
end.
worker() ->
timer:sleep(1000),
exit(crashed).
6.2 unlink #
erlang
-module(unlink_demo).
-export([demo/0]).
demo() ->
Pid = spawn_link(fun() -> timer:sleep(1000) end),
unlink(Pid),
io:format("Unlinked from: ~p~n", [Pid]).
七、进程监控 #
7.1 monitor #
erlang
-module(monitor_demo).
-export([demo/0]).
demo() ->
Pid = spawn(fun() ->
timer:sleep(1000),
exit(normal)
end),
Ref = monitor(process, Pid),
io:format("Monitoring: ~p~n", [Pid]),
receive
{'DOWN', Ref, process, Pid, Reason} ->
io:format("Process down: ~p~n", [Reason])
end.
7.2 demonitor #
erlang
-module(demonitor_demo).
-export([demo/0]).
demo() ->
Pid = spawn(fun() -> timer:sleep(5000) end),
Ref = monitor(process, Pid),
demonitor(Ref),
io:format("Demonitored~n").
7.3 link vs monitor #
| 特性 | link | monitor |
|---|---|---|
| 方向 | 双向 | 单向 |
| 多次监控 | 不支持 | 支持 |
| 主动取消 | unlink | demonitor |
| 适用场景 | 相关进程 | 监控进程 |
八、进程退出 #
8.1 exit/1 #
erlang
-module(exit_demo).
-export([demo/0]).
demo() ->
spawn(fun() ->
timer:sleep(1000),
exit(normal)
end),
spawn(fun() ->
timer:sleep(2000),
exit(abnormal)
end).
8.2 exit/2 #
erlang
-module(exit_signal).
-export([demo/0]).
demo() ->
Pid = spawn(fun() ->
receive
_ -> ok
end
end),
timer:sleep(100),
exit(Pid, kill).
8.3 退出原因 #
| 原因 | 说明 |
|---|---|
normal |
正常退出 |
shutdown |
关闭 |
{shutdown, Term} |
带原因的关闭 |
kill |
强制杀死 |
| 其他 | 异常退出 |
九、总结 #
本章学习了:
- 进程特点
- 创建进程
- 进程标识符
- 进程状态
- 进程注册
- 进程链接
- 进程监控
- 进程退出
准备好学习消息传递了吗?让我们进入下一章。
最后更新:2026-03-27