Всем вам, банку / клиенту, которые недавно залили SO вопросами:
В эрланге термин thread
не существует.Они называются processes
.Базовая реализация не имеет значения.Пожалуйста, не говорите thread
снова ни в одном из ваших сообщений об erlang.
Ваш учитель отстой.Если вы действительно хотите выучить эрланг, купите Programming Erlang
, прочитайте его и выполните все упражнения.
Я создаю проект клиента / банка erlang и хочупередать список кортежей различным потокам (ProcessID), чтобы каждый раз, когда поток изменял некоторые значения в списке, другие потоки / процессы также работали с одной и той же копией списка.
Вы рассмотрели OTPgen_servers еще?Gen_server устанавливает отношения клиент-сервер, где клиенты могут запросить у gen_server текущее значение списка.Клиенты также могут изменить значение списка.Gen_server входит в рекурсивный цикл, например:
loop(State) ->
receive
{get_state} ->
%send State to client
loop(State);
{set_state, 10} ->
loop([10|NewState])
end
end
Когда вы запускаете gen_server, State может быть списком, например, []
или [1, 2, 3]
.Клиенты могут отправлять сообщения на сервер, чтобы получить значение переменной State или установить переменную State.
Я новичок в Erlang (всего 4 дня)
Тогда вы не сможете написать программу: все, что вы можете сделать, это попросить других людей написать код для вас.Что в этом хорошего?Почему ваш учитель считал, что после 4 дней изучения эрланга вы могли бы написать многопроцессную программу?
К настоящему времени я могу создать процесс для всех банков и клиентов, и клиенты могут звонитьбанк обрабатывает и вычитает деньги, но этот вычет происходит только в копии банковского списка, который есть у процесса клиента.Как я могу иметь универсальную / глобальную копию или копию списка кортежей, передаваемую по ссылке, чтобы она могла совместно обрабатываться различными процессами.
Основной принцип erlang (и все остальныефункциональные языки) заключается в том, что ни один процесс не может изменить данные, над которыми работает другой процесс.Все, что вы можете сделать, это отправить копию данных в другой процесс.Если процесс банка должен знать, сколько находится на счете клиента, он может отслеживать остаток в рекурсивном цикле:
init(Deposit) ->
loop(Deposit).
loop(Balance) ->
receive
{From, {deduct, Amount}} ->
case Balance >= Amount of
true ->
From ! whatever,
bank(Balance - Amount);
_ ->
From ! whatever
bank(Balance)
end
end.
Вы также можете добавить сообщение deposit
в предложение receive:
{From, {deposit, Amount}} ->
From ! whatever,
bank(Balance + Amount)
Balance
также может быть списком кортежей, где каждый кортеж является учетной записью клиента, с более подходящим именем переменной, скажем, Balances
.Чтобы найти клиента в списке Balances
, вы можете использовать lists:keyfind()
;чтобы удалить старый баланс, вы можете использовать lists:keydelete()
, а чтобы добавить новый баланс в список, вы можете сделать: [{Pid, NewBalance} | Balances]
.