что случится с порожденным процессом, если умирающий модуль, который его порождает? - PullRequest
0 голосов
/ 08 мая 2019

Если модуль A имеет метод someMethod (). Если этот метод порожден как поток из этого модуля A, и если код внутри someMethod () является бесконечным циклом, то в этом случае, если модуль A выходит из строя, будет ли порожденный поток, выполняющий «someMethod», также выключаться?

По сути, я хочу знать, существует ли несколько потоков, порожденных из модуля, и если этот модуль выйдет из строя, все ли эти порожденные потоки будут отключены / уничтожены автоматически? или они будут продолжать работать (при условии, что код, который выполняется этими потоками, имеет бесконечный цикл)

Ответы [ 3 ]

3 голосов
/ 08 мая 2019

Модули не выходят из строя. Процессы делают. Модули могут быть удалены из памяти, если загружено более одной новой версии, и тогда все процессы, которые запускают старую версию, будут уничтожены, но это не то, что вы просили. Модули не выходят из строя. Процессы делают.

1 голос
/ 08 мая 2019

В Erlang процесс A порождает другой процесс B. В зависимости от того, какое поведение вы хотите, B продолжайте выполнять .... если процесс B выполняет работу, которая не связана с данными, или необходимо связаться с процессом A, таким как ссылки A иB или монитор A, процесс B сделает все для вас и не заботится о процессе A.

Это причина, по которой некоторые крупные телекоммуникационные системы имеют поведение Fallover / Takeover для решения этой проблемы.Им нужно, чтобы 2 основных процесса работали параллельно и контролировали друг друга.Например: A - это sub, а B - главный, оба они вместе контролируют процессы тысяч сыновей (S1, S2, S3 ...).

enter image description here

когда процесс B получает проблему, процесс A немедленно берет данные из процесса и продолжает работу своего сына, а затем перезапускает процесс B. Все они зависят от поведения вашего приложения, которое вы хотите построить

0 голосов
/ 11 мая 2019

Если вы спрашиваете:

Если я создаю два процесса, которые выполняют одну и ту же функцию в модуле, и первый процесс умирает, второй процесс тоже умирает?

Попробуйте это:

-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, произошла ошибка, но вывод Салли продолжается:

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() оба процесса будут связаны с процессом оболочки (потому что я вызову test() в оболочке, а процесс, вызывающий spawn_link(), является другой стороной ссылки). Затем, если Pid1 умирает, Pid1 заставит процесс оболочки умереть, и поскольку процесс оболочки связан с Pid2, это означает, что Pid2 также умрет. Кстати, когда процесс оболочки умирает, автоматически запускается другой процесс оболочки (с другим 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>, и поэтому новый процесс оболочки не выводит сообщения об ошибках <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> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...