如果模块A具有方法someMethod()。如果此方法是从模块A作为线程生成的,并且someMethod()中的代码是无限循环,则在这种情况下,如果模块A发生故障,则执行“ someMethod”的生成的线程也将发生故障吗? / p>
我基本上想知道某个模块是否产生了多个线程,并且如果该模块出现故障,那些产生的所有线程是否会自动断开/杀死?否则它们将继续运行(假设这些线程正在执行的代码是无限循环的)
答案 0 :(得分:3)
模块不会崩溃。流程做。如果您加载了多个新版本,则可以从内存中清除模块,然后所有运行旧版本的进程将被杀死,但这不是您要的。模块不会掉线。流程就可以。
答案 1 :(得分:1)
在Erlang中,进程A产生另一个进程B。根据您希望B继续执行的行为....如果进程B执行与数据无关或需要与进程A进行通信的工作,例如链接A和B或监视器A,流程B会为您做任何事情,而不必关心流程A。
这就是为什么某些大型电信系统具有故障转移/接管行为来解决此问题的原因。他们需要2个主要进程并行运行并互相监视。例如:A是子项,B是主项,它们一起监视着数千个儿子的进程(S1,S2,S3 ...)。
当进程B遇到问题时,进程A将立即从进程中获取数据并继续其子进程,然后重新启动进程B。所有这些都取决于您要构建的应用程序的行为
答案 2 :(得分:0)
如果您要询问:
如果我产生了两个在模块中执行相同功能的进程, 并且第一个过程死亡,第二个过程也死亡吗?
尝试一下:
-module(my).
-compile(export_all).
get_divisor(X, Id) when is_integer(X) ->
Result = 10/X,
io:format("Process ~w: 10/~w = ~w~n", [Id, X, Result]),
timer:sleep(1000),
get_divisor(X-1, Id).
test() ->
Pid1 = spawn(my, get_divisor, [10, harry]),
Pid2 = spawn(my, get_divisor, [20, sally]),
io:format("harry's pid = ~w~nsally's pid = ~w~n", [Pid1, Pid2]).
在外壳中:
~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3 (abort with ^G)
1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> my:test().
harry's pid = <0.71.0>
sally's pid = <0.72.0>
Process harry: 10/10 = 1.0
Process sally: 10/20 = 0.5
ok
Process harry: 10/9 = 1.1111111111111112
Process sally: 10/19 = 0.5263157894736842
Process harry: 10/8 = 1.25
Process sally: 10/18 = 0.5555555555555556
开始输出后,在外壳中快速发出i() command
(信息):
3> i().
Pid Initial Call Heap Reds Msgs
Registered Current Function Stack
<0.0.0> otp_ring0:start/2 376 990 0
init init:loop/1 2
<0.1.0> erts_code_purger:start/0 233 11 0
erts_code_purger erts_code_purger:wait_for_request 0
<0.2.0> erts_literal_area_collector:start 233 3 0
erts_literal_area_collector:msg_l 5
<0.3.0> erts_dirty_process_code_checker:s 233 3 0
erts_dirty_process_code_checker:m 1
<0.6.0> erlang:apply/2 6772 713103 0
erl_prim_loader erl_prim_loader:loop/3 5
<0.32.0> gen_event:init_it/6 987 414 0
error_logger gen_event:fetch_msg/6 10
<0.33.0> erlang:apply/2 1598 954 0
application_controlle gen_server:loop/7 7
<0.35.0> application_master:init/4 233 69 0
application_master:main_loop/2 7
<0.36.0> application_master:start_it/4 233 90 0
application_master:loop_it/4 5
<0.37.0> supervisor:kernel/1 987 2202 0
kernel_sup gen_server:loop/7 10
<0.38.0> erlang:apply/2 6772 142009 0
code_server code_server:loop/1 3
<0.40.0> rpc:init/1 233 32 0
rex gen_server:loop/7 10
<0.41.0> global:init/1 233 63 0
global_name_server gen_server:loop/7 10
<0.42.0> erlang:apply/2 233 25 0
global:loop_the_locker/1 5
<0.43.0> erlang:apply/2 233 3 0
global:loop_the_registrar/0 2
<0.44.0> inet_db:init/1 233 350 0
inet_db gen_server:loop/7 10
<0.45.0> global_group:init/1 233 74 0
global_group gen_server:loop/7 10
<0.46.0> file_server:init/1 1598 3436 0
file_server_2 gen_server:loop/7 10
<0.47.0> gen_event:init_it/6 233 51 0
erl_signal_server gen_event:fetch_msg/6 10
<0.48.0> supervisor_bridge:standard_error/ 233 50 0
standard_error_sup gen_server:loop/7 10
<0.49.0> erlang:apply/2 233 11 0
standard_error standard_error:server_loop/1 2
<0.50.0> supervisor_bridge:user_sup/1 233 72 0
gen_server:loop/7 10
<0.51.0> user_drv:server/2 1598 7176 0
user_drv user_drv:server_loop/6 9
<0.52.0> group:server/3 233 88 0
user group:server_loop/3 4
<0.53.0> group:server/3 196650 89053 0
group:server_loop/3 4
<0.54.0> kernel_config:init/1 233 48 0
gen_server:loop/7 10
<0.55.0> supervisor:kernel/1 376 282 0
kernel_safe_sup gen_server:loop/7 10
<0.59.0> supervisor:disk_log_sup/1 233 147 0
disk_log_sup gen_server:loop/7 10
<0.60.0> disk_log_server:init/1 610 91 0
disk_log_server gen_server:loop/7 10
<0.61.0> disk_log:init/2 6772 36424 0
disk_log:loop/1 5
<0.63.0> erlang:apply/2 17731 4082 0
shell:shell_rep/4 17
<0.64.0> erlang:apply/2 318187 45309 0
c:pinfo/1 50
<0.71.0> my:get_divisor/2 233 59 0
timer:sleep/1 5
<0.72.0> my:get_divisor/2 233 59 0
timer:sleep/1 5
Total 565674 1046833 0
283
ok
在以上输出的底部,您可以看到my:get_divisor/2
在进程<0.71.0>
和进程<0.72.0>
中都在运行。而且,如果您查看iex行2>
的输出,则可以看到:
2> my:test().
harry's pid = <0.71.0>
sally's pid = <0.72.0>
确认这些是test()
函数产生的过程。
两个生成的进程的输出继续:
Process harry: 10/7 = 1.4285714285714286
Process sally: 10/17 = 0.5882352941176471
Process harry: 10/6 = 1.6666666666666667
Process sally: 10/16 = 0.625
Process harry: 10/5 = 2.0
Process sally: 10/15 = 0.6666666666666666
Process harry: 10/4 = 2.5
Process sally: 10/14 = 0.7142857142857143
Process harry: 10/3 = 3.3333333333333335
Process sally: 10/13 = 0.7692307692307693
Process harry: 10/2 = 5.0
Process sally: 10/12 = 0.8333333333333334
Process harry: 10/1 = 10.0
Process sally: 10/11 = 0.9090909090909091
Process sally: 10/10 = 1.0
4>
=ERROR REPORT==== 10-May-2019::20:40:51 ===
Error in process <0.71.0> with exit value:
{badarith,[{my,get_divisor,2,[{file,"my.erl"},{line,5}]}]}
最后一行说流程<0.71.0>
,即流程harry
发生错误,但sally的输出仍在继续:
Process sally: 10/9 = 1.1111111111111112
Process sally: 10/8 = 1.25
Process sally: 10/7 = 1.4285714285714286
Process sally: 10/6 = 1.6666666666666667
Process sally: 10/5 = 2.0
Process sally: 10/4 = 2.5
Process sally: 10/3 = 3.3333333333333335
Process sally: 10/2 = 5.0
Process sally: 10/1 = 10.0
4>
=ERROR REPORT==== 10-May-2019::20:41:01 ===
Error in process <0.72.0> with exit value:
{badarith,[{my,get_divisor,2,[{file,"my.erl"},{line,5}]}]}
上面的最后一行显示,现在过程<0.72.0>
,即过程sally
出现错误。
如果再次使用i() command
,将会看到<0.71.0>
和<0.72.0>
两个进程都不再运行。
i().
Pid Initial Call Heap Reds Msgs
Registered Current Function Stack
<0.0.0> otp_ring0:start/2 376 990 0
init init:loop/1 2
<0.1.0> erts_code_purger:start/0 233 11 0
erts_code_purger erts_code_purger:wait_for_request 0
<0.2.0> erts_literal_area_collector:start 233 3 0
erts_literal_area_collector:msg_l 5
<0.3.0> erts_dirty_process_code_checker:s 233 3 0
erts_dirty_process_code_checker:m 1
<0.6.0> erlang:apply/2 6772 714364 0
erl_prim_loader erl_prim_loader:loop/3 5
<0.32.0> gen_event:init_it/6 2586 3251 0
error_logger gen_event:fetch_msg/6 10
<0.33.0> erlang:apply/2 1598 954 0
application_controlle gen_server:loop/7 7
<0.35.0> application_master:init/4 233 69 0
application_master:main_loop/2 7
<0.36.0> application_master:start_it/4 233 90 0
application_master:loop_it/4 5
<0.37.0> supervisor:kernel/1 987 2202 0
kernel_sup gen_server:loop/7 10
<0.38.0> erlang:apply/2 6772 142119 0
code_server code_server:loop/1 3
<0.40.0> rpc:init/1 233 32 0
rex gen_server:loop/7 10
<0.41.0> global:init/1 233 63 0
global_name_server gen_server:loop/7 10
<0.42.0> erlang:apply/2 233 25 0
global:loop_the_locker/1 5
<0.43.0> erlang:apply/2 233 3 0
global:loop_the_registrar/0 2
<0.44.0> inet_db:init/1 233 350 0
inet_db gen_server:loop/7 10
<0.45.0> global_group:init/1 233 74 0
global_group gen_server:loop/7 10
<0.46.0> file_server:init/1 1598 3436 0
file_server_2 gen_server:loop/7 10
<0.47.0> gen_event:init_it/6 233 51 0
erl_signal_server gen_event:fetch_msg/6 10
<0.48.0> supervisor_bridge:standard_error/ 233 50 0
standard_error_sup gen_server:loop/7 10
<0.49.0> erlang:apply/2 233 11 0
standard_error standard_error:server_loop/1 2
<0.50.0> supervisor_bridge:user_sup/1 233 72 0
gen_server:loop/7 10
<0.51.0> user_drv:server/2 987 19868 0
user_drv user_drv:server_loop/6 9
<0.52.0> group:server/3 233 114 0
user group:server_loop/3 4
<0.53.0> group:server/3 196650 153779 0
group:server_loop/3 4
<0.54.0> kernel_config:init/1 233 48 0
gen_server:loop/7 10
<0.55.0> supervisor:kernel/1 376 282 0
kernel_safe_sup gen_server:loop/7 10
<0.59.0> supervisor:disk_log_sup/1 233 147 0
disk_log_sup gen_server:loop/7 10
<0.60.0> disk_log_server:init/1 610 91 0
disk_log_server gen_server:loop/7 10
<0.61.0> disk_log:init/2 6772 36600 0
disk_log:loop/1 5
<0.63.0> erlang:apply/2 17731 4277 0
shell:shell_rep/4 17
<0.64.0> erlang:apply/2 318187 81397 0
c:pinfo/1 50
Total 566196 1164826 0
273
ok
5>
Erlang还允许您将一个进程link
切换到另一个进程,如果其中一个进程死了,这将导致两个进程都死掉:
-module(my).
-compile(export_all).
get_divisor(X, Id) when is_integer(X) ->
Result = 10/X,
io:format("Process ~w: 10/~w = ~w~n", [Id, X, Result]),
timer:sleep(1000),
get_divisor(X-1, Id).
test() ->
Pid1 = spawn_link(my, get_divisor, [10, harry]),
Pid2 = spawn_link(my, get_divisor, [20, sally]),
io:format("shell pid = ~w~n", [self()]),
io:format("harry's pid = ~w~nsally's pid = ~w~n", [Pid1, Pid2]).
“ spawn_link()”可以读作“ spawn_and_link()”。在test()
中,两个进程都将链接到Shell进程(因为我将在Shell中调用test()
,而调用spawn_link()
的进程是链接的另一端)。然后,如果Pid1死亡,则Pid1将导致Shell进程终止,并且由于Shell进程链接到Pid2,这意味着Pid2也将终止。顺便说一句,当Shell进程终止时,另一个Shell进程(具有不同的pid)将自动启动。
在外壳中:
~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3 (abort with ^G)
1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> my:test().
shell pid = <0.64.0>
Process harry: 10/10 = 1.0
Process sally: 10/20 = 0.5
harry's pid = <0.71.0>
sally's pid = <0.72.0>
ok
Process harry: 10/9 = 1.1111111111111112
Process sally: 10/19 = 0.5263157894736842
Process harry: 10/8 = 1.25
Process sally: 10/18 = 0.5555555555555556
Process harry: 10/7 = 1.4285714285714286
Process sally: 10/17 = 0.5882352941176471
Process harry: 10/6 = 1.6666666666666667
Process sally: 10/16 = 0.625
Process harry: 10/5 = 2.0
Process sally: 10/15 = 0.6666666666666666
Process harry: 10/4 = 2.5
Process sally: 10/14 = 0.7142857142857143
Process harry: 10/3 = 3.3333333333333335
Process sally: 10/13 = 0.7692307692307693
Process harry: 10/2 = 5.0
Process sally: 10/12 = 0.8333333333333334
Process harry: 10/1 = 10.0
Process sally: 10/11 = 0.9090909090909091
Process sally: 10/10 = 1.0
** exception error: an error occurred when evaluating an arithmetic expression
in function my:get_divisor/2 (my.erl, line 5)
3>
=ERROR REPORT==== 11-May-2019::12:06:18 ===
Error in process <0.71.0> with exit value:
{badarith,[{my,get_divisor,2,[{file,"my.erl"},{line,5}]}]}
这就是输出的结尾。您没有看到来自进程<0.72.0>
的错误,因为当进程<0.71.0>
死亡时,它导致外壳死亡(即使这些错误消息的输出被颠倒了),并且新外壳自动启动过程对进程<0.72.0>
一无所知,因此新的Shell进程不会输出进程<0.72.0>
的错误消息。
如果使用i()
,则可以看到以下进程均未运行:
shell process = <0.64.0>
...
...
harry's pid = <0.71.0>
sally's pid = <0.72.0>
3> i().
=ERROR REPORT==== 10-May-2019::21:17:19 ===
Error in process <0.71.0> with exit value:
{badarith,[{my,get_divisor,2,[{file,"my.erl"},{line,5}]}]}
3> i().
Pid Initial Call Heap Reds Msgs
Registered Current Function Stack
<0.0.0> otp_ring0:start/2 376 990 0
init init:loop/1 2
<0.1.0> erts_code_purger:start/0 233 11 0
erts_code_purger erts_code_purger:wait_for_request 0
<0.2.0> erts_literal_area_collector:start 233 3 0
erts_literal_area_collector:msg_l 5
<0.3.0> erts_dirty_process_code_checker:s 233 3 0
erts_dirty_process_code_checker:m 1
<0.6.0> erlang:apply/2 6772 714804 0
erl_prim_loader erl_prim_loader:loop/3 5
<0.32.0> gen_event:init_it/6 1598 1848 0
error_logger gen_event:fetch_msg/6 10
<0.33.0> erlang:apply/2 1598 954 0
application_controlle gen_server:loop/7 7
<0.35.0> application_master:init/4 233 69 0
application_master:main_loop/2 7
<0.36.0> application_master:start_it/4 233 90 0
application_master:loop_it/4 5
<0.37.0> supervisor:kernel/1 987 2202 0
kernel_sup gen_server:loop/7 10
<0.38.0> erlang:apply/2 6772 142113 0
code_server code_server:loop/1 3
<0.40.0> rpc:init/1 233 32 0
rex gen_server:loop/7 10
<0.41.0> global:init/1 233 63 0
global_name_server gen_server:loop/7 10
<0.42.0> erlang:apply/2 233 25 0
global:loop_the_locker/1 5
<0.43.0> erlang:apply/2 233 3 0
global:loop_the_registrar/0 2
<0.44.0> inet_db:init/1 233 350 0
inet_db gen_server:loop/7 10
<0.45.0> global_group:init/1 233 74 0
global_group gen_server:loop/7 10
<0.46.0> file_server:init/1 1598 3436 0
file_server_2 gen_server:loop/7 10
<0.47.0> gen_event:init_it/6 233 51 0
erl_signal_server gen_event:fetch_msg/6 10
<0.48.0> supervisor_bridge:standard_error/ 233 50 0
standard_error_sup gen_server:loop/7 10
<0.49.0> erlang:apply/2 233 11 0
standard_error standard_error:server_loop/1 2
<0.50.0> supervisor_bridge:user_sup/1 233 72 0
gen_server:loop/7 10
<0.51.0> user_drv:server/2 2586 12209 0
user_drv user_drv:server_loop/6 9
<0.52.0> group:server/3 233 101 0
user group:server_loop/3 4
<0.53.0> group:server/3 318187 86312 0
group:server_loop/3 4
<0.54.0> kernel_config:init/1 233 48 0
gen_server:loop/7 10
<0.55.0> supervisor:kernel/1 376 282 0
kernel_safe_sup gen_server:loop/7 10
<0.59.0> supervisor:disk_log_sup/1 233 147 0
disk_log_sup gen_server:loop/7 10
<0.60.0> disk_log_server:init/1 610 91 0
disk_log_server gen_server:loop/7 10
<0.61.0> disk_log:init/2 6772 37458 0
disk_log:loop/1 5
<0.63.0> erlang:apply/2 17731 4978 0
shell:shell_rep/4 17
<0.74.0> erlang:apply/2 318187 39091 0
c:pinfo/1 50
Total 688344 1047971 0
273
ok
4>