Есть вот такой код:
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
Здравствуйте, 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.
Здравствуйте, 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>
Суть похоже в выделенном, т.е. не может переменная привязки совпадать с именем параметра функции.
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.
Здравствуйте, 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.