如何将顺序计算方法转换为并发方法?代码实现困惑求助
修正你的Erlang并发计算实现
嘿,我瞅了下你的代码,问题在于你现在的P(Y,Z)和Q(Y,Z)还是同步顺序调用的,根本没用到Erlang的进程并发能力。要真正实现并发计算加法和乘法,得让这两个运算在独立的进程里跑,再把结果回传给主进程做除法。我给你一步步梳理修正方案:
第一步:把P和Q改成消息驱动的进程
让它们接收目标进程ID(PID)和计算参数,算出结果后主动发回给指定进程:
% 并发计算Y+Z,结果发送给传入的PID p(TargetPid, Y, Z) -> Sum = Y + Z, TargetPid ! {sum_result, Sum}. % 并发计算Z*Y,结果发送给传入的PID q(TargetPid, Y, Z) -> Product = Z * Y, TargetPid ! {product_result, Product}.
第二步:改造cc进程,实现并发调度与结果收集
cc()需要先启动两个计算进程,然后等待两个结果都返回后再做除法。这里我给你写两种实现方式:
方式1:简单顺序接收(适合确定消息顺序的场景)
cc() -> receive {Y, Z} -> % 启动加法和乘法的独立进程,把自己的PID传给它们,让结果发回来 spawn(?MODULE, p, [self(), Y, Z]), spawn(?MODULE, q, [self(), Y, Z]), % 等待加法结果 receive {sum_result, P} -> ok end, % 等待乘法结果 receive {product_result, Q} -> ok end, % 计算最终结果并输出(你可以换成自己的处理逻辑) FinalResult = P / Q, io:format("最终结果:~p~n", [FinalResult]) end.
方式2:更健壮的结果收集(不依赖消息接收顺序)
如果担心加法和乘法的结果谁先到,用循环收集的方式更稳妥:
cc() -> receive {Y, Z} -> spawn(?MODULE, p, [self(), Y, Z]), spawn(?MODULE, q, [self(), Y, Z]), % 调用辅助函数收集两个结果 collect_results(undefined, undefined) end. % 辅助函数:循环等待,直到拿到两个结果 collect_results(Sum, Product) when is_number(Sum), is_number(Product) -> % 两个结果都齐了,计算最终值 FinalResult = Sum / Product, io:format("最终结果:~p~n", [FinalResult]); collect_results(Sum, Product) -> receive {sum_result, NewSum} -> collect_results(NewSum, Product); {product_result, NewProduct} -> collect_results(Sum, NewProduct) end.
第三步:run()函数保持原样即可
run() -> Pid = spawn(?MODULE, cc, []), Pid ! {10, 12}.
为啥这样改就对了?
spawn/3会创建全新的Erlang进程,加法和乘法会同时运行,真正实现并发self()获取当前cc进程的PID,让计算进程知道把结果发给谁- 结果收集逻辑确保等两个计算都完成后,再执行除法,避免未定义的错误
测试一下,运行your_module:run().,会输出最终结果:0.18333333333333332(也就是22/120的结果),和顺序计算完全一致,但加法和乘法是并发执行的~
内容的提问来源于stack exchange,提问作者Ryan1
相关产品推荐
相关产品推荐

