Как передать список ссылок на несколько потоков в Erlang? - PullRequest
0 голосов
/ 17 июня 2019

Я создаю проект клиент / банк erlang и хочу передать список кортежей различным потокам (ProcessID), чтобы каждый раз, когда поток изменял некоторые значения в списке, другие потоки / процессы также работали с одной и той же копиейсписок.

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

Pid = spawn(customer, bazCust, [Name, Loan]),
T = {Name, Pid, Loan},
Pid ! {self(), Name, Loan, Pid, BankPidList},
get_feedback(),

Используемый выше список BankPidList выглядит следующим образом:

[{rbc,<0.2067.0>,800},{bmo,<0.2068.0>,700},{ing,<0.2069.0>,200},0]

Я довольно новичок в Erlang (всего 4 дня), так что может быть какое-то искусство, которое я не очень эффективно использую, но мне просто нужно, чтобы функциональность была не зависит от эффективности на данный момент.

Ответы [ 2 ]

2 голосов
/ 18 июня 2019

Всем вам, банку / клиенту, которые недавно залили SO вопросами:

  1. В эрланге термин thread не существует.Они называются processes.Базовая реализация не имеет значения.Пожалуйста, не говорите thread снова ни в одном из ваших сообщений об erlang.

  2. Ваш учитель отстой.Если вы действительно хотите выучить эрланг, купите 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].

0 голосов
/ 25 июня 2019

Не слишком усложняя язык, я завершил свой проект, построив модуль банка и передав его идентификаторы процесса всем остальным клиентам. Клиенты вносят изменения в этот идентификатор процесса (отправляя сообщение / почту по

PID!{IDENTIFIER,{parameters}}

вместо внесения изменений в собственную локальную копию. Вы можете упростить свою работу, зарегистрировав идентификаторы процесса с именем модуля (или некоторым конкретным именем)

register(Name, Pid)

но для начинающих, таких как я, при повторном запуске модуля выдается много ошибок (не знаю почему, но решение состоит в том, чтобы завершить процесс и снова скомпилировать). Опять же, я новичок в Erlang и могу пропустить правильную терминологию для конкретного языка. Ниже приведена ссылка на мой код https://github.com/NitinNanda/Scalable-Message-Passing-Bank-Client.git

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...