如果产生它的模块死亡,那么产生的过程会怎样?

时间:2019-05-08 08:18:12

标签: multithreading erlang

如果模块A具有方法someMethod()。如果此方法是从模块A作为线程生成的,并且someMethod()中的代码是无限循环,则在这种情况下,如果模块A发生故障,则执行“ someMethod”的生成的线程也将发生故障吗? / p>

我基本上想知道某个模块是否产生了多个线程,并且如果该模块出现故障,那些产生的所有线程是否会自动断开/杀死?否则它们将继续运行(假设这些线程正在执行的代码是无限循环的)

3 个答案:

答案 0 :(得分:3)

模块不会崩溃。流程做。如果您加载了多个新版本,则可以从内存中清除模块,然后所有运行旧版本的进程将被杀死,但这不是您要的。模块不会掉线。流程就可以。

答案 1 :(得分:1)

在Erlang中,进程A产生另一个进程B。根据您希望B继续执行的行为....如果进程B执行与数据无关或需要与进程A进行通信的工作,例如链接A和B或监视器A,流程B会为您做任何事情,而不必关心流程A。

这就是为什么某些大型电信系统具有故障转移/接管行为来解决此问题的原因。他们需要2个主要进程并行运行并互相监视。例如:A是子项,B是主项,它们一起监视着数千个儿子的进程(S1,S2,S3 ...)。

enter image description here

当进程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>