[Erlang] - два способа работы с потоком
От: DemAS http://demas.me
Дата: 16.02.09 10:52
Оценка:
Есть вот такой код:

register_db_server()->
    register(db_serv, start_db_server()).

start_db_server()->
    spawn(fun prepare_db_server/0).

prepare_db_server()->
    loop_db_server(dict:new()).
    
loop_db_server(GlobalDict)->
    receive
    {From, {dict, Dict}} ->
            io:format("uuuuu~n"),
        From ! {self(), "done"},
        io:format("ooooo~n"),
        loop_db_server(Dict);
    {From, {finish}}->
        io:format("db_sever shutdown~n");
end.

db_rpc(Pid, Dict)->
    Pid ! {self(), Dict},
    io:format("rpc sent~n"),
    receive
    {Pid, Responce}->
        io:format("rpc responce~n"),
        Responce
    end.

process_dict(Pid, Dict)->
    db_rpc(Pid, Dict),
    io:format("end process~n").

print_result(Pid)->
    db_rpc(Pid, {print}).

shutdown_db_server(Pid)->
    db_rpc(Pid, {finish}).

create_test_dict()->
    D1 = dict:new(),
    D2 = dict:store("a", 5, D1),
    D3 = dict:store("b", 2, D2),
    D4 = dict:store("c", 1, D3).

test()->
    register_db_server(),
    D = create_test_dict(),
    process_dict(db_serv, {dict, D}),
    process_dict(db_serv, {dict, D}),
    shutdown_db_server(db_serv).    

test2()->
    Pid = start_db_server(),
    D = create_test_dict(),
    process_dict(Pid, {dict, D}),
    process_dict(Pid, {dict, D}),
    shutdown_db_server(Pid).


Если вызвать test2(), то получим следующий результат:

2> db_server:test2().
rpc sent
uuuuu
ooooo
rpc responce
end process
rpc sent
uuuuu
ooooo
rpc responce
end process
rpc sent
db_sever shutdown


Все работает. Единственное — не появляется приглашение "3>". Просто
процесс висит. Почему и как победить?

Если же выполнить test(), то результат будет таким:

2> db_server:test().
rpc sent
uuuuu
ooooo


То есть, все "повиснет" гораздо раньше. Почему так происходит и как
забороть?
Posted via RSDN NNTP Server 2.1 beta
Re: [Erlang] - два способа работы с потоком
От: DrDred Россия  
Дата: 16.02.09 14:06
Оценка: 5 (1)
Здравствуйте, DemAS, Вы писали:

Мои правки, так работает. Но вот почему, надо еще внимательно курить

loop_db_server(GlobalDict)->
    receive
    {From, {dict, Dict}} ->
            io:format("uuuuu~n"),
        From ! {self(), "done"},
        io:format("ooooo~n"),
        loop_db_server(Dict);
    {From, {finish}}->
        io:format("db_sever shutdown~n"),
        From ! {self(), "finish"}
    end.

db_rpc(Pid, Dict)->
    Pid ! {self(), Dict},
    io:format("rpc sent~n"),
    receive
    {_, Responce}->
        io:format("rpc responce~n"),
        Responce
    end.
--
WBR, Alexander
Re[2]: [Erlang] - два способа работы с потоком
От: DrDred Россия  
Дата: 16.02.09 15:32
Оценка:
Здравствуйте, DrDred, Вы писали:

DD>Здравствуйте, DemAS, Вы писали:


DD>
DD>loop_db_server(GlobalDict)->
DD>    receive
DD>    {From, {dict, Dict}} ->
DD>            io:format("uuuuu~n"),
DD>        From ! {self(), "done"},
DD>        io:format("ooooo~n"),
DD>        loop_db_server(Dict);
DD>    {From, {finish}}->
DD>        io:format("db_sever shutdown~n"),
DD>        From ! {self(), "finish"}
DD>    end.

DD>db_rpc(Pid, Dict)->
DD>    Pid ! {self(), Dict},
DD>    io:format("rpc sent~n"),
DD>    receive
DD>    {_, Responce}->
DD>    {PidNew, Responce}->
[/b]
DD>        io:format("rpc responce~n"),
DD>        Responce
DD>    end.
DD>


Суть похоже в выделенном, т.е. не может переменная привязки совпадать с именем параметра функции.
--
WBR, Alexander
Re: [Erlang] - два способа работы с потоком
От: ArtDenis Россия  
Дата: 16.02.09 18:32
Оценка: 5 (1)
DAS>То есть, все "повиснет" гораздо раньше. Почему так происходит и как
DAS>забороть?

всё очень просто
db_rpc(Pid, Dict)->
    Pid ! {self(), Dict},
    io:format("rpc sent~n"),
    receive
    {Pid, Responce}-> % Вот здесь мы ожидаем плучить Pid равный атому db_serv 
                      % (в случае с разегистрированыым сервером). А приходит реальный Pid сервера. 
                      % Ерланг не бросает исключений в этом случае. Он оставляет сообщение в очереди процесса
                      % пока для него не появится подходящий патерн в каком-нибудь receive
        io:format("rpc responce~n"),
        Responce
    end.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: [Erlang] - два способа работы с потоком
От: DemAS http://demas.me
Дата: 17.02.09 09:47
Оценка:
Здравствуйте, DrDred, Вы писали:

DD>> receive

DD>DD> {_, Responce}->
DD>[/b]

А что значит _? Любая переменная?
Re[4]: [Erlang] - два способа работы с потоком
От: DrDred Россия  
Дата: 17.02.09 10:39
Оценка:
Здравствуйте, DemAS, Вы писали:


DD>>> receive

DD>>DD> {_, Responce}->
DD>>[/b]

DAS>А что значит _? Любая переменная?


Да

The anonymous variable is denoted by underscore (_) and can be used when a variable is required but its value can be ignored.

--
WBR, Alexander
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.