Erlang多进程/多函数创建进程及ParallelJoin进程异常处理问题
解决Erlang进程管理与ParallelJoin进程问题
1. 多进程/多函数创建与进程链接
在Erlang里,创建进程最常用的是spawn/1、spawn/3(指定模块、函数、参数);如果需要让进程感知对方的退出状态,就用spawn_link/1或spawn_link/3建立进程链接。
举个实际用法例子:
- 从匿名函数创建独立进程:
Pid = spawn(fun() -> taskTwo() end) - 从指定模块函数创建并建立链接:
spawn_link(model, taskThree, [])
进程链接的核心作用是:当被链接的进程终止时,当前进程会收到EXIT信号(默认会跟着终止,除非开启陷阱EXIT);如果是正常退出,也会向链接进程发送{'EXIT', Pid, normal}消息(需要开启陷阱EXIT才能捕获)。
2. 将系统进程接收的信号转换为消息
要把EXIT信号转换成可处理的消息,你需要在目标进程中设置trap_exit标志,调用process_flag(trap_exit, true)即可。
比如在ParallelJoin进程启动时先执行这个操作:
parallel_join() -> process_flag(trap_exit, true), % 开启EXIT陷阱,把系统信号转为可接收的消息 % 后续消息处理逻辑 ...
设置后,当链接的进程退出时,ParallelJoin进程就会在消息队列中收到{'EXIT', Pid, Reason}格式的消息,而不是直接被终止,你可以在receive代码块里自定义处理逻辑。
3. 修复ParallelJoin进程,让taskFive正常执行
你提到taskFive未执行,大概率是因为ParallelJoin进程没有正确捕获关联进程的EXIT消息,或者没等到所有关联进程退出就中断了逻辑。下面是完整的可运行代码,解决这个问题:
-module(model). -compile(export_all). start() -> % 创建ParallelJoin主进程 ParallelPid = spawn(model, parallel_join, []), % 创建三个任务进程并与ParallelJoin建立链接 spawn_link(model, taskTwo, [ParallelPid]), spawn_link(model, taskThree, [ParallelPid]), spawn_link(model, taskFour, [ParallelPid]), ok. % 模拟任务进程:执行后正常退出 taskTwo(_Parent) -> io:format("Task Two is running~n"), timer:sleep(1000), exit(normal). taskThree(_Parent) -> io:format("Task Three is running~n"), timer:sleep(1500), exit(normal). taskFour(_Parent) -> io:format("Task Four is running~n"), timer:sleep(2000), exit(normal). % ParallelJoin主进程逻辑 parallel_join() -> % 开启EXIT陷阱,接收关联进程的退出消息 process_flag(trap_exit, true), % 等待3个任务进程全部正常退出 wait_for_tasks(3), % 所有任务完成后启动taskFive spawn(model, taskFive, []). % 计数等待任务退出 wait_for_tasks(0) -> ok; wait_for_tasks(Remaining) -> receive {'EXIT', _Pid, normal} -> io:format("Received normal exit signal from task~n"), wait_for_tasks(Remaining - 1); % 忽略其他无关消息 _UnrelatedMsg -> wait_for_tasks(Remaining) end. % 最终要执行的taskFive taskFive() -> io:format("Task Five is running! 🎉~n"), timer:sleep(1000), io:format("Task Five completed successfully~n").
关键修复点:
- 开启EXIT陷阱:
parallel_join/0开头的process_flag(trap_exit, true)是核心,没有它,ParallelJoin进程会在第一个关联进程退出时被直接终止,根本无法走到启动taskFive的步骤。 - 计数等待所有任务:
wait_for_tasks/1函数会一直阻塞等待,直到收到3个正常退出的消息,确保所有关联进程都完成后才启动taskFive。 - 进程链接:用
spawn_link创建taskTwo、taskThree、taskFour,确保它们的退出信号能传递给ParallelJoin进程。
你可以编译运行这个代码验证效果:
c(model). model:start().
内容的提问来源于stack exchange,提问作者Kiros
相关产品推荐
相关产品推荐

