Erlang OTP之terminate 深入分析

EGO_Planner代码学习(三):px4ctrl代码流程 上节阅读了EGO_Planner的轨迹服务器部分的代码,其实质是将规划器生成的轨迹进行离散化,间隔10ms计算当前时刻在轨迹上的位置,并发送到话题上。这两天抽空看了下控制器部分的代码,在l这个软件包里,它的功能是进行px4的模式识别和上层控制,通过线性控制器把发布过来的位置命令解算成飞控的控制量,通过mavros发送给px4。下面就详细看一下它的启动过程。 阅读详情

 转载:庆亮的博客-webgame架构

一、terminate简述及问题产生

 

terminate是gen_server的一个回调函数,如果一个gen_server进程设置了trap_exit为true(process_flag(trap_exit, true)),则在该进程结束时会自动调用terminate。利用这个功能,我们可以在进程退出时进行一些善后工作,例如持久化数据、清理等等。但实际上terminate不一定有时间完成所有的任务,在此之前可能已经被系统强制结束了(如果使用init:stop形式结束beam)。

 

二、测试terminate

一个erlang 内部 process结束有两种形式:主动结束(如玩家下线后,玩家进程会自动结束)和被动结束(init:stop)。

系统停止时(init:stop/c:q/erlang:halt),会依次停止所有的进程,如果一个进程是监控树,则该监控树会先依次停止所有的子进程,然后结束自己。对于子进程也是同样的处理方法。

 

先做测试,后分析源码。测试分为四种情况:

 

进程主动退出 + simple_one_for_one

init:stop + simple_one_for_one

进程主动退出 + one_for_one

init:stop + one_for_one

 

源码文件:

test.erl (application)

test_sup.erl (supervisor)

test_server.erl (gen_server)

 

test.erl源码:

 

-module(test).

-behaviour(application).

-export([start/0, start/2, stop/1]).

start() ->
    application:start(test).

start(_StartType, _StartArgs) ->
    case test_sup:start_link() of
        {ok, Pid} ->
            {ok, Pid};
        Error ->
            Error
    end.

stop(_State) ->
    ok.

 

非常简单,直接通过 erl -name test@192.168.1.83 -setcookie 123456 -boot start_sasl -s test start 即可启动该app。

 

test_sup.erl源码:

 

-module(test_sup).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

-define(SERVER, ?MODULE).

start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

init([]) ->
    RestartStrategy = simple_one_for_one,
    MaxRestarts = 1000,
    MaxSecondsBetweenRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},

    Restart = transient,
    Shutdown = 200000,
    Type = worker,

    AChild = {test_server, {test_server, start_link, []},
              Restart, Shutdown, Type, [test_server]},

    {ok, {SupFlags, [AChild]}}.

 

源码骨架都是emacs生成的,我们只关注RestartStrategy = simple_one_for_one,这里,等会需要改成one_for_one以便测试对比。

 

test_server.erl

 

-module(test_server).

-behaviour(gen_server).

-export([
         start/0,
         start_link/0
        ]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-define(SERVER, ?MODULE).

-record(state, {}).

start() ->
    {ok, _} = supervisor:start_child(test_sup, []).

start_link() ->
    gen_server:start_link(?MODULE, [], []).

init([]) ->
    erlang:process_flag(trap_exit, true),
    {ok, #state{}}.

handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info({'EXIT', _, Reason}, State) ->
    io:format("exit:~p~n", [Reason]),
    {stop, normal, State};

handle_info(_Info, State) ->
    {noreply, State}.

terminate(Reason, _State) ->
    io:format("i'm terminate:~p~n", [Reason]),
    timer:sleep(10000),
    io:format("~s", ["end"]),
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

 

简单说明下test_server:

2. handle_info({'EXIT', _, Reason}, State) -> 方便simple_one_for_one下进程进程退出操作

3. terminate中的清理工作:io → timer:sleep → io

 

启动命令行:erl -name test@192.168.1.83 -setcookie 123456 -boot start_sasl -s test start

 

 

1. 进程主动退出 + simple_one_for_one

(test@192.168.1.83)1> erlang:exit(list_to_pid("<0.51.0>"), test).

exit:test

true

i'm terminate:normal

(test@192.168.1.83)2> end

 

正常完成了terminate

 

2. init:stop + simple_one_for_one

 

 (test@192.168.1.83)1> test_server:start().

{ok,<0.53.0>}

(test@192.168.1.83)2> init:stop().

ok

(test@192.168.1.83)3> i'm terminate:shutdown

[root@ming2_local_dev test]#

可以看到似乎没能正常的处理完terminate

 

3. 进程主动退出 + one_for_one

(test@192.168.1.83)1> erlang:exit(list_to_pid("<0.51.0>"), test).

exit:test

true

i'm terminate:normal

(test@192.168.1.83)2> end

 

正常完成了terminate

 

4. init:stop + one_for_one

(test@192.168.1.83)2> init:stop().

ok

(test@192.168.1.83)3> i'm terminate:shutdown

end[root@ming2_local_dev test]#

 

ok,很完整的执行了我们的terminate。

 

terminate执行测试结果

 

 

Simple_one_for_one

One_for_one

进程主动退出

完整执行

完整执行

init:stop

不能完整执行

完整执行

 

三、底层分析

看起来很奇怪的结果,还是从源码来分析问题。从supervisor开始:

 

 

terminate(_Reason, State) ->
    terminate_children(State#state.children, State#state.name),
    ok.

 

terminate_children/2 是一个尾递归函数,依次结束每个子进程:

terminate_children(Children, SupName) ->
    terminate_children(Children, SupName, []).

terminate_children([Child | Children], SupName, Res) ->
    NChild = do_terminate(Child, SupName),
    terminate_children(Children, SupName, [NChild | Res]);
terminate_children([], _SupName, Res) ->
    Res.

  

在看do_terminate/2

 

do_terminate(Child, SupName) when Child#child.pid =/= undefined ->
    case shutdown(Child#child.pid,
          Child#child.shutdown) of
    ok ->
        Child#child{pid = undefined};
    {error, OtherReason} ->
        report_error(shutdown_error, OtherReason, Child, SupName),
        Child#child{pid = undefined}
    end;
do_terminate(Child, _SupName) ->
    Child.

 

继续:

shutdown(Pid, brutal_kill) ->
 
    case monitor_child(Pid) of
    ok ->
        exit(Pid, kill),
        receive
        {'DOWN', _MRef, process, Pid, killed} ->
            ok;
        {'DOWN', _MRef, process, Pid, OtherReason} ->
            {error, OtherReason}
        end;
    {error, Reason} ->     
        {error, Reason}
    end;

shutdown(Pid, Time) ->
   
    case monitor_child(Pid) of
    ok ->
        exit(Pid, shutdown), %% Try to shutdown gracefully
        receive
        {'DOWN', _MRef, process, Pid, shutdown} ->
            ok;
        {'DOWN', _MRef, process, Pid, OtherReason} ->
            {error, OtherReason}
        after Time ->
            exit(Pid, kill),  %% Force termination.
            receive
            {'DOWN', _MRef, process, Pid, OtherReason} ->
                {error, OtherReason}
            end
        end
;
    {error, Reason} ->     
        {error, Reason}
    end.

 

 

Ok,结束子进程时分情况处理了,先看看monitor_child/1,代码注释的比较详细,简单的说是用于处理child自己退出的情况。

 

monitor_child(Pid) ->
   
    %% Do the monitor operation first so that if the child dies
    %% before the monitoring is done causing a 'DOWN'-message with
    %% reason noproc, we will get the real reason in the 'EXIT'-message
    %% unless a naughty child has already done unlink…

    erlang:monitor(process, Pid),
    unlink(Pid),

    receive
    %% If the child dies before the unlik we must empty
    %% the mail-box of the 'EXIT'-message and the 'DOWN'-message.

    {'EXIT', Pid, Reason} ->
        receive
        {'DOWN', _, process, Pid, _} ->
            {error, Reason}
        end
    after
0 ->
        %% If a naughty child did unlink and the child dies before
        %% monitor the result will be that shutdown/2 receives a
        %% 'DOWN'-message with reason noproc.
        %% If the child should die after the unlink there
        %% will be a 'DOWN'-message with a correct reason
        %% that will be handled in shutdown/2.

        ok  
    end.

 

回头看shutdown/2,主要区别在于exit(Pid, Reason)这一行,如果子进程的shutdown策略为brutal_kill,则子进程被直接kill,而kill消息是不能被捕捉的,也就不存在terminate被调用的可能了(terminate能被调用是因为捕捉了{‘EXIT’,_, _}消息,详细情况请自行查看gen_server实现)。如果你想在退出时清理数据,这里一定不能设置为brutal_kill,而是设置为一个较大的时间数值(毫秒),用于等待子进程做善后工作:

exit(Pid, shutdown), %% Try to shutdown gracefully
        receive
        {'DOWN', _MRef, process, Pid, shutdown} ->
            ok;
        {'DOWN', _MRef, process, Pid, OtherReason} ->
            {error, OtherReason}
        after Time ->
            exit(Pid, kill),  %% Force termination.
            receive
            {'DOWN', _MRef, process, Pid, OtherReason} ->
                {error, OtherReason}
            end
如果在指定时间内,子进程尚未结束,则强制kill。

 

从这一块的源码中我们没有看到restart strategy(one_for_one …)对terminate的影响,这跟上面的测试结果不太吻合。过一遍supervisor的代码,发现针对simple_one_for_one和one_for_one的子进程的启动过程是不同的:

 

handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) ->
    #child{mfa = {M, F, A}} = hd(State#state.children),
    Args = A ++ EArgs,
    case do_start_child_i(M, F, Args) of
    {ok, Pid} ->
        NState = State#state{dynamics =
                 ?DICT:store(Pid, Args, State#state.dynamics)},
        {reply, {ok, Pid}, NState};
    {ok, Pid, Extra} ->
        NState = State#state{dynamics =
                 ?DICT:store(Pid, Args, State#state.dynamics)},
        {reply, {ok, Pid, Extra}, NState};
    What ->
        {reply, What, State}
    end;

%%% The requests terminate_child, delete_child and restart_child are
%%% invalid for simple_one_for_one supervisors.

handle_call({_Req, _Data}, _From, State) when ?is_simple(State) ->
    {reply, {error, simple_one_for_one}, State};

handle_call({start_child, ChildSpec}, _From, State) ->
    case check_childspec(ChildSpec) of
    {ok, Child} ->
        {Resp, NState} = handle_start_child(Child, State),
        {reply, Resp, NState};
    What ->
        {reply, {error, What}, State}
    end;

 

simple_one_for_one形式启动的子进程根本没有放在supervisor的state.children里面,也就是说supervisor在terminate的时候根本没管simple_one_for_one形式启动的子进程,如此当supervisor结束时,所有的simple_one_for_one子进程都会收到一条{‘EXIT’, Pid, Reason}的消息,如果子进程有处理这样的消息并返回了stop,则会调用terminate。 但在执行terminate期间,app可能已经结束,从而正在停止中的系统会直接kill掉该进程(实际上是所有剩余的进程),使得其没有时间执行完所有的功能代码(参考之前的分析《init:stop浅析》)。

 

四、结论、问题与解决办法

 

1.  结论

 

 

Simple_one_for_one

One_for_one

进程主动退出

完整执行

完整执行

init:stop

不能完整执行

完整执行

 

 

2.  问题

使用simple_one_for_one时,在系统关闭时,可能无法正常的完成某些的善后工作,如数据持久等等

 

3.  解决办法

使用one_for_one,但是one_for_one的启动过程需要做一些简单的调整:

 

sup树的init返回:

 

  init([]) ->
    RestartStrategy = one_for_one,
    MaxRestarts = 1000,
    MaxSecondsBetweenRestarts = 3600,
    SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},
    {ok, {SupFlags, []}}.

 

start_child的时候childspec需要拼凑spec id:

supervisor:start_child(mod_stall_sup,
                       {lists:concat(["mod_stall_server_", MAPID]),
                        {mod_stall_server, start_link, [MAPID]},
                        transient, 30000, worker, [mod_stall_server]})  

 

revit二次开发环境搭建(2024版)(小白友好) revit二次开发环境配置,SDK、addin manager和lookup新手友好安装教程 阅读详情

相关推荐

【SABRE 3D, SABRE 3DxT,LAM设备】2025年9月12日-生产期间维护用的双重隔离

生产期间维护用的双重隔离。该程序用于准备将一个或多个双工位设置为维护状态,同时SABRE 3D/3DxT/3D Scimitar保持生产运行。其目的是在不中断生产的情况下将双工位与运行中的设备隔离。

weixin_46735260的博客 574

erlang的terminate解析

一个erlang application启动之后,通常需要在一定时间后停止

pyf725324的专栏 927

新手避坑指南:HT7036计量芯片SPI读取电压的完整流程(从复位到校准)

本文详细介绍了HT7036计量芯片的SPI读取电压完整流程,从硬件准备到校准设置,重点解析了复位引脚处理、SPI通信配置、芯片初始化及数据处理等关键步骤。针对常见问题如晶振焊接、SPI时序错误等提供实用解决方案,帮助开发者高效完成电压测量与校准。

weixin_30070339的博客 326

RabbitMQ消息追踪插件rabbitmq_tracing

RabbitMQ消息追踪 目的: 追踪mq的消息的来源和去向,并且查看消息的具体内容 方法: rabbitmq官方提供了一个rabbitmq_tracing插件可以完成目标 部署: 一、开启rabbitmq的tracing插件 #rabbitmq-plugins enable rabbitmq_tracing 开启tracing插件mq的web页面可以看到admin标签页多了一个选项 二、配置追...

xuangey的博客 6632

Augustus手动安装教程

本文记载了如何结合conda手动安装Augustus

m0_65437087的博客 1256

SAP BOM批量反查代码分享

SAP BOM反查批量查询代码分享

我小时候很黑的博客 4972

erlang mysql:start_link_Erlang OTP之terminate 深入分析

gen_server进程设置了trap_exit为true(process_flag(trap_exit,true)),则在该进程结束时会自动调用terminate。利用这个功能,我们可以在进程退出时进行一些善后工作,例如持久化数据、清理等等。但实际上terminate不一定有时间完成所有的任务,在此之前可能已经被系统强制结束了(如果使用init:stop形式结束beam)。二、测试termina...

weixin_33404102的博客 327

基于STM32的智能电子秤设计毕业论文

摘要:本文设计了一款基于STM32F103C8T6的智能电子秤系统,通过HX711称重传感器实现高精度测量,采用OLED显示和矩阵键盘完成人机交互。系统包含重量采集、数据处理、单价设置、去皮清零及总价计算等功能模块,经测试测量误差小于0.1%,稳定性良好。研究实现了低成本、高可靠性的智能称重方案,为后续无线传输和AI算法集成奠定了基础。关键词:STM32;智能电子秤;HX711;OLED显示;矩阵键盘。

3254968421的博客 849

Erlang的gen_server的terminate使用的几点总结

(1)terminate只有在捕获到信号的情况下,即收到{'Exit‘,From,Reason}消息时,里面被执行,因此必须设置process_flag(trap_exit,true);      能捕获信号的情况:     a、gen_server主动退出:正常退出执行了stop方法和异常退出(代码本身的问题所致,如无匹配,逻辑语法错误等或是执行了exit(pid,test))     b

zcc_0015的专栏 5497

手把手教你学simulink(57.3)--电励磁同步电动机场景示例:基于Simulink的自适应控制(Adaptive Control)电励磁同步电动机

目录基于Simulink的自适应控制(Adaptive Control)电励磁同步电动机项目实例1. 项目背景2. 系统架构2.1 电励磁同步电动机模型2.2 三相逆变器模型2.3 自适应控制器(Adaptive Controller)2.4 系统框图3. 模型设计3.1 创建Simulink模型3.2 自适应控制(Adaptive Control)设计3.3 仿真环境搭建4. 参数优化4.1 自动调优5. 实际应用案例5.1 工业驱动系统5.2 风力发电系统6. 结论需求分析电励磁同步电动机(Electr

MHD0815的博客 504

某东详情页h5st 算法分析

某东详情页h5st 算法分析

自成背后的博客 1万+

erlang gen_server terminate

原文地址 总结一下: 使用exit(Pid,Reason)时: gen_server设置了trap_exit为false时,不会进行信号的转换, 1.Reason为normal,gen_server不退出,terminate不执行; 2.Reason为test、shutdown、kill、other时。gen_server退出,terminate不执行 gen_server设置了trap_exit...

牛逼! 454

华为OD机试 - 幸运数字(Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题。

学Java,找哪吒 3775

Erlang/Otp gen_server terminate

gen_server定义了6个call_back接口: init

enjolras的专栏 1378

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

18岁的工程师谈 Erlang/OTP(2)

虚拟银行 ErlyBank 与 gen_server本文是介绍Erlang/OTP系列文章的第一篇。场景:银行ErlyBank的服务器开始运行,银行要求它成为可伸缩的系统,以便管理重要的顾客帐户。听说了Elang的强大功能后,银行雇用我们建造这一系统。为了测验我们的能力,银行首先要求我们建个简单的服务器,处理银行帐户开立和注销、存款、取款这几项业务。他们只要软件原型,无须满足实际需求。结果:我们将

lawme的专栏 4959

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Erlang OTP Application 核心原理与实践:从概念到完整项目构建

在分布式系统与高并发编程领域,进程管理与容错机制是构建可靠系统的基石。Erlang/OTP 通过监督树(Supervision Tree)和进程隔离等核心原理,为开发者提供了成熟的容错框架。其技术价值在于能够构建出具备自我修复能力、高可用的软实时系统。在实际应用场景中,OTP Application 作为运行时单元,封装了监督树、进程组及其生命周期,是 OTP 设计哲学中封装与依赖管理的具体体现。理解 OTP Application 如何定义应用边界、管理启动顺序,并协调多个 **监督树** 构成完整系统,

weixin_33748818的博客 469

Erlang/OTP gen_server实战指南:构建高可靠并发服务器的5个关键步骤

想要构建能够处理百万级并发连接的系统吗?Erlang/OTP的gen_server行为模式正是你需要的解决方案。作为Erlang/OTP平台的核心组件,gen_server为开发者提供了一个标准化框架,用于创建可靠、可扩展的服务器进程,广泛应用于分布式系统、实时通信和微服务架构。 ## 为什么选择gen_server? 在当今的高并发应用场景中,传统的线程模型往往难以应对大规模并发请求。Erl

gitblog_00130的博客 749

Erlang之supervisor入门

1.概念: supervisor是OTP框架四大行为之一,它用于监视别的进程,当一个进程崩溃是,它能够快速重启该进程,并根据不同的策略做出不同的行为。 2.常用函数: 1.start_link({local/global,NAME}, MODULE, Args). 创建一个supervisor的进程服务器,local为本地进程,global为全局进程,NAME为该进程名,...

fbher的博客 1305

Erlang/OTP gen_server终极指南:构建高可靠分布式系统的核心模式

在构建高并发、分布式系统时,Erlang/OTP的gen_server行为模式是你必须掌握的核心技术。这个强大的服务器框架为开发者提供了标准化、可靠的进程管理方案,让你能够专注于业务逻辑而不是底层并发细节。无论你是Erlang新手还是经验丰富的开发者,理解gen_server都将显著提升你构建健壮系统的能力。 ## 🚀 项目简介与核心价值 Erlang/OTP是一个专门为构建高可用、分布式、

gitblog_00464的博客 465

[Erlang 0023] 理解Erlang/OTP gen_server

Erlang的OTP behaviour是对一些通用编程模式的抽象,在用Erlang 语言做开发时可以在behavior基础上快速构建出可用且可靠的功能.OTP behaviour包含gen_server gen_event gen_fsm supervisor.其中绝大多数情况下都是在使用gen_server,supervisor本身也是使用gen_server实现的.我们就以 gen_serv

风花雪月 奋斗-ing 997

深入理解gen_smtp架构:OTP风格回调模块设计与扩展技巧

gen_smtp是一个功能强大的可扩展Erlang SMTP客户端和服务器库,采用OTP(开放电信平台)设计原则构建,为开发者提供了灵活的回调机制和模块化架构。本文将深入探讨gen_smtp的核心架构设计,重点解析其OTP风格的回调模块实现,并分享实用的扩展技巧,帮助开发者更好地理解和使用这个优秀的开源库。 ## OTP架构基础:回调模块设计理念 OTP是Erlang生态系统的基石,其设计思想

gitblog_00376的博客 406

深入解析Erlang/OTP Runtime Application:从概念到实战构建高可用系统

在分布式系统架构中,应用容器是组织和管理进程的核心单元,它通过统一的声明式配置和生命周期管理,为高并发服务提供基础支撑。其原理在于将相关进程模块化打包,通过监督树机制实现进程的启动、监控和容错恢复,从而提升系统的可维护性和可靠性。这一技术价值在于能够构建出具备“任其崩溃”哲学的高可用服务,广泛应用于电信、金融和即时通讯等对容错性要求极高的领域。本文聚焦于Erlang/OTP的Runtime Application,通过拆解其启动流程和实战构建,帮助开发者掌握这一核心框架。文中涉及的**监督树**和**进程容

weixin_34189116的博客 307

dotfiles 的 Pi Calm 扩展源码完整剖析:动画小船渲染、零侵入过滤与优雅降级实现原理

dotfiles 是一个用 Nix 管理的个人开发环境仓库,其中藏着一个精致的 Pi 本地扩展——**Pi Calm**。它在 AI 编码代理 Pi 工作时,用一行动画小船替代默认的状态行,并"无痕"隐藏工具调用的外壳与折叠的思考内容,同时绝不改动任何会话数据。本文带你逐行看懂它三大核心机制的实现原理:动画小船渲染、零侵入过滤、优雅降级。 ## 先认识 Pi Calm:一个"只改显示、不动数据"

gitblog_00526的博客 860

深入理解OTP Application:从概念到实践的运行时容器解析

在构建高可用、可维护的分布式系统时,进程管理与生命周期控制是核心挑战。Erlang/OTP框架通过标准化的组件抽象来解决这些工程化问题,其中OTP Application作为关键容器,定义了组件的生命周期、依赖关系和运行时行为。其原理基于静态资源文件与动态进程树的映射,通过Application Master、回调模块和根监督树三层结构实现统一管理。这一设计为系统提供了开箱即用的启动顺序控制、配置管理和错误隔离能力,特别适用于需要7x24小时运行、支持热更新的电信或即时通讯场景。通过理解OTP Applic

weixin_30326515的博客 315

erlang OTP gen_server 图解分析

http://www.hoterran.info/otp-gen_server-sourcecode 在阅读erlang的otp源码gen_server.erl的时候,一直想写点什么,用一种最好的方式表达出来,最终却总是没法表达清楚,困惑之余看到这篇文章,作者用图解的方式,非常清晰明了的表达了我一直想表达的东西,下面是原文链接: http://www.hoterran.info/otp-gen...

weixin_30587927的博客 105

深入解析OTP Application运行时机制:从监督树到生产实践

在分布式系统架构中,进程管理与生命周期控制是保障服务稳定性的核心技术。OTP(Open Telecom Platform)作为Erlang的核心框架,通过其Application机制,为开发者提供了一套标准化的应用打包、启动与生命周期管理方案。Application不仅是一个代码容器,更是一套定义了应用如何被系统识别、启动和监控的元数据规范,其核心在于构建由监督者(Supervisor)和工作进程(Worker)组成的监督树,以此实现进程的层次化管理和自动容错。从技术价值看,这套机制极大地提升了系统的可维护

445

ERLANG/OTP学习 Day3

gen_server 接口方法,gen_server:start_link(local,Name),Mod,...)会启动一个本地的服务器,当{local,Name}中的local为global时,会启动一个可以被erlang节点集群访问的全局服务器,Mod参数时回调的模块名,gen_server:call(?回调函数handle info(Info,state)被用来处理发给服务器的自发性消息。gen_server:cast(Name,Msg)实现了一个播发 (cast),是一个是没有返回值的调用.

weixin_48283045的博客 114
上一篇: Erlang/OTP's global module
下一篇: OTP中supervisor启动过程
jamesjun
博客等级 码龄19年 25粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值