热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Erlang入门:构建application练习4(进程link的作用)

1、示例项目(bank)简介bank_server.erl是为客户服务的进程回调模块bank_center.erl是为银行服务中心的进程回调模块客户(bank_serve

1、示例项目(bank)简介

技术分享

bank_server.erl是为客户服务的进程回调模块
bank_center.erl是为银行服务中心的进程回调模块
客户(bank_server)每年都要扣除年费
所有年费都交给银行服务中心(bank_center)

客户服务使用示例:
创建用户:bank_server:create_account(myname, 100).
用户存钱:myname ! {deposit, 10}.
用户取钱:myname ! {cash1, 20}.
myname ! {cash2, 30}.
查询余额:myname ! check.

银行服务中心使用示例:
查询收到的年费总额:bank_center ! check.


2、启动bank_center

2.1、bank_center里有3个启动API

%% 此处?MODULE为bank_center

start()->
%% gen_server:start/3
%% 无link,无注册
{ok, Pid} = gen_server:start(?MODULE, [], []),
%% 自行注册
erlang:register(?MODULE, Pid).

start2()->
%% gen_server:start/4
%% 无link,注册为本地进程,名称为?MODULE
gen_server:start({local, ?MODULE}, ?MODULE, [], []).

start_link()->
%% gen_server:start_link/4
%% 有link,有注册
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

用start/0或start2/0是无link的,start_link/0是有link的。

2.2、在bank_app里启动bank_center

-module(bank_app).
-behaviour(application). 
-export([start/2, stop/1]). 

-include("common.hrl").

start(_Type, _Args) -> 
?I("Start ~p ...", [?MODULE]),
% bank_center:start(),
% bank_center:start2(),
bank_center:start_link(),
{ok, self()}.

stop(_State) -> 
?I("Stop ~p!", [?MODULE]),
ok.

在上面start/2里调用bank_center:start/0或bank_center:start2/0启动后,
执行appmon:start()查看bank进程,如下:
技术分享
在上面start/2里调用bank_center:start_link/0启动后,
执行appmon:start()查看bank进程,如下:
技术分享

3、创建客户进程后,和bank_center进行link

bank_server.erl中的init/1
init([Money]) ->
%% 与银行服务中心进行关联
link(whereis(bank_center)),
{ok, Money}.

4、link实验

4.1、测试link的作用

link方式启动bank_center并且创建一个客户:
bank_server:create_account(myname1, 100).
whereis(bank_center)查看bank_center进程ID,返回不为undefined说明bank_center进程存在
向客户进程发送一个错误:
myname1 ! error.
此时myname1异常退出,whereis(bank_center)和whereis(myname1)都返回undefined,说明这两个进程都已经终止。
Eshell V5.10.4 (abort with ^G)
1> bank_server:create_account(myname1, 100).
true
2> whereis(bank_center).
<0.37.0>
3> myname1 ! error.
##[<0.38.0>bank_server:141] terminate: {bad_return_value,{ok,80}}
error
4> 
=ERROR REPORT==== 16-Jan-2015::16:54:58 ===
** Generic server <0.38.0> terminating 
** Last message in was error
** When Server state == 80
** Reason for termination == 
** {bad_return_value,{ok,80}}

4> whereis(bank_center).
undefined
5> whereis(myname1). 
undefined
小结:用link进行关联的进程组中,只要其中一个进程终止,其他也会同时终止。

4.2、设置bank_center为系统进程,并且能监控客户进程的退出

设置bank_center为系统进程:
bank_center.erl中的init/1
init(_) ->
%% 把系统进程设置为系统进程
process_flag(trap_exit, true),
?I("Start ~p ...", [?MODULE]),
{ok, 0}.
演示过程如下:
Eshell V5.10.4 (abort with ^G)
1> bank_server:create_account(myname1, 100).
true
2> 
2> myname1 ! error.
##[<0.38.0>bank_server:141] terminate: {bad_return_value,{ok,100}}
##[<0.37.0>bank_center:81] handle_info: {&#39;EXIT&#39;,<0.38.0>,
{bad_return_value,{ok,100}}}
error
3> 
=ERROR REPORT==== 16-Jan-2015::17:12:34 ===
** Generic server <0.38.0> terminating 
** Last message in was error
** When Server state == 100
** Reason for termination == 
** {bad_return_value,{ok,100}}

3> whereis(bank_center).
<0.37.0>
4> whereis(myname1). 
undefined
whereis(myname1).返回undefined说明已经终止。
whereis(bank_center)返回了PID,说明没有终止,并且收到了myname1的退出消息:
{&#39;EXIT&#39;, <0.38.0>, {bad_return_value,{ok,100}}}
消息中指明了退出的PID及退出原因。
以上都是以异常的方式让进程退出的,现在测试一下正常退出的情况:
Eshell V5.10.4 (abort with ^G)
1> bank_server:create_account(myname1, 100).
true
2> myname1 ! stop2.
##[<0.38.0>bank_server:141] terminate: normal
##[<0.37.0>bank_center:81] handle_info: {&#39;EXIT&#39;,<0.38.0>,normal}
stop2
正常退出不会报错,收到了正常退出消息:{‘EXIT‘,<0.38.0>,normal}

小结:通过process_flag(trap_exit, true)将进程设置为系统,不但不会随着别的进程退出而退出,还能监控其他进程的退出情况。
问题:如果系统进程内部发生了错误而异常退出,将会出现什么情况?


5、完整演示代码下载

地址:http://download.csdn.net/detail/u011471961/8368973

Erlang入门:构建application练习4(进程link的作用)


推荐阅读
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
author-avatar
路很长别太狂_297
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有