如何通过引用将元组列表传递给 Erlang 中的多个线程?

How to pass-by-reference a List of Tuples to multiple threads in Erlang?

我正在构建一个 client/Bank erlang 项目,我希望将一个元组列表传递给各种线程 (ProcessIDs),这样每当一个线程更改列表中的某些值时,其他 threads/processes 也会处理列表的同一副本。

这是必需的,因为我希望客户线程进行一些计算并从银行扣除余额。 到目前为止,我可以为所有银行和客户创建一个流程,客户可以调用银行流程并扣款,但这种扣款只发生在客户流程拥有的银行列表副本中。 我怎样才能拥有元组列表的 universal/global 副本或按引用传递的副本,以便不同进程可以相互处理。

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 天),所以可能有些技巧我没有非常有效地使用,但我现在只需要完成功能而不考虑效率。

致所有 bank/client 最近充满问题的人:

  1. 在 erlang 中,术语 thread 不存在。他们被称为processes。底层实现无关紧要。请不要在任何关于 erlang 的帖子中再次说 thread

  2. 你的老师很烂。如果你真的想学习 erlang,请购买 Programming Erlang、阅读它并完成所有练习。

I am building a client/Bank erlang project and I wish to pass a List of tuples to various threads(ProcessIDs) so that whenever a thread changes some values in the List, other threads/processes also work on the same copy of the list.

你已经覆盖 OTP gen_servers 了吗? gen_server 建立了一个 client-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 变量。

I am quite new to Erlang (just 4 days)

那你就不会写程序了,只能请人家帮你写代码。那有什么好处?为什么你的老师认为在学习 erlang 4 天之后你可以编写一个多进程程序?

By now, I am able to create a process for all banks and customers and customers are able to call the bank process and deduct the money, but this deduction is only happening in the copy of bank list that the customer process has. How can I have a universal/global copy or Pass-by-reference copy of the List of tuples so it can be mutually worked upon by different processes.

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 消息:

    {From, {deposit, Amount}} ->
        From ! whatever,
        bank(Balance + Amount)

Balance 也可以是元组列表,其中每个元组是一个客户帐户,具有更合适的变量名称,例如 Balances。要在 Balances 列表中查找客户,您可以使用 lists:keyfind();要删除旧余额,您可以使用 lists:keydelete(),要将新余额添加到列表中,您可以这样做:[{Pid, NewBalance} | Balances].

由于语言不太复杂,我通过构建一个银行模块并将其进程 ID 传递给所有其他客户来完成我的项目。客户更改此 processId(通过

发送 message/mail
PID!{IDENTIFIER,{parameters}}

而不是对自己的本地副本进行更改。 您可以通过使用模块名称(或某些特定名称)注册 processIds 来简化您的工作

register(Name, Pid)

但是对于像我这样的初学者来说,当你re-run这个模块时,它会给出很多错误(不知道为什么,但解决方案是终止进程并重新编译)。同样,我是 Erlang 的初学者,可能会错过正确的 language-specific 术语。 以下是我的代码的 link https://github.com/NitinNanda/Scalable-Message-Passing-Bank-Client.git